Полное руководство по хукам жизненного цикла Vue в Vue3

Хуки жизненного цикла в и Vue2, и Vue3 работают очень одинаково - у нас по-прежнему есть доступ к одним и тем же хукам, и мы по-прежнему хотим использовать их для тех же сценариев использования.

Если в нашем проекте используется API параметров, нам не нужно изменять какой-либо код для наших хуков жизненного цикла Vue. Это связано с тем, что Vue3 разработан, чтобы быть совместимым с предыдущими выпусками Vue.

Однако способ доступа к этим хукам немного отличается, когда мы решаем использовать Composition API, что особенно полезно в более крупных проектах Vue.

К концу этой статьи вы узнаете, как использовать хуки жизненного цикла как в Options API, так и в Composition API, и будете на пути к написанию лучшего кода.

Пойдем!

Содержание

  1. Что такое хуки жизненного цикла Vue
  2. Использование хуков жизненного цикла Vue в API опций
  3. Использование хуков жизненного цикла Vue3 в Composition API
  4. Обновление кода Vue2 до хуков жизненного цикла Vue3
  5. Взгляд на каждый крючок жизненного цикла в Vue2 и Vue3
  6. Крючки для создания
  7. Монтажные крючки
  8. Обновить хуки
  9. Крюки разрушения
  10. Крючки активации
  11. Новые хуки отладки в Vue3
  12. Заключение

Что такое хуки жизненного цикла Vue

Во-первых, давайте посмотрим на схему хуков жизненного цикла Vue3 в обоих API опций и Composition API. Это должно дать общий обзор того, что происходит, прежде чем мы сможем углубиться в детали.

По сути, каждое основное событие жизненного цикла Vue разделено на два перехватчика, которые вызываются непосредственно перед этим событием, а затем сразу после него. Есть четыре основных события (8 основных хуков), которые вы можете использовать в своем приложении Vue.

  • Создание - запускается при создании вашего компонента.
  • Монтаж - запускается, когда DOM смонтирован.
  • Обновления - запускается при изменении реактивных данных
  • Разрушение - запускается прямо перед тем, как ваш элемент будет уничтожен.

Использование наших хуков жизненного цикла Vue в API опций

С помощью API параметров наши хуки жизненного цикла доступны как параметры в нашем экземпляре Vue. Нам не нужно ничего импортировать, мы можем просто вызвать метод и написать код для этой ловушки жизненного цикла.

Например, предположим, что мы хотели получить доступ к нашим mounted() и updated() хукам жизненного цикла. Это может выглядеть примерно так.

<script>     
   export default {         
      mounted() {             
         console.log('mounted!')         
      },         
      updated() {             
         console.log('updated!')         
      }     
   }
</script>

Достаточно просто, правда?

Хорошо. Перейдем к использованию хуков жизненного цикла Vue 3 в Composition API.

Использование наших хуков жизненного цикла Vue в API композиции Vue3

В Composition API мы должны импортировать хуки жизненного цикла в наш проект, прежде чем мы сможем их использовать. Это сделано для того, чтобы проекты были максимально легкими.

import { onMounted } from 'vue'

За исключением beforeCreate и created (которые заменены самим методом setup), есть 9 хуков жизненного цикла Options API, к которым мы можем получить доступ в нашем методе настройки.

  • onBeforeMount - вызывается перед началом монтажа
  • onMounted - вызывается при монтировании компонента
  • onBeforeUpdate - вызывается при изменении реактивных данных и перед повторным рендерингом
  • onUpdated - вызывается после повторного рендеринга
  • onBeforeUnmount - вызывается перед уничтожением экземпляра Vue
  • onUnmounted - вызывается после уничтожения экземпляра
  • onActivated - вызывается, когда активирован поддерживаемый компонент
  • onDeactivated - вызывается при деактивации поддерживаемого компонента
  • onErrorCaptured - вызывается при обнаружении ошибки дочерним компонентом

Когда мы импортируем их и получаем к ним доступ в нашем коде, это будет выглядеть так.

<script>
import { onMounted } from 'vue'

export default {
   setup () {
     onMounted(() => {
       console.log('mounted in the composition api!')
     })
   }
}
</script>

Обновление кода Vue2 до хуков жизненного цикла Vue3

Это удобное сопоставление жизненного цикла Vue2 и Vue3 прямо из документации Vue3 Composition API, и я думаю, что это один из самых полезных способов точно увидеть, как все будет меняться и как мы можем их использовать.

  • beforeCreate - ›использовать setup()
  • created - ›использовать setup()
  • beforeMount -> onBeforeMount
  • mounted -> onMounted
  • beforeUpdate -> onBeforeUpdate
  • updated -> onUpdated
  • beforeDestroy -> onBeforeUnmount
  • destroyed -> onUnmounted
  • errorCaptured -> onErrorCaptured

Углубленный взгляд на каждую ловушку жизненного цикла

Теперь мы понимаем две важные вещи:

  1. Различные хуки жизненного цикла, которые мы можем использовать
  2. Как использовать их как в API опций, так и в API композиции

Давайте глубже погрузимся в каждый крючок жизненного цикла и посмотрим, как они используются, какой код мы можем написать в каждом из них, и чем они отличаются в Options API и Composition API.

Крючки для создания - начало жизненного цикла VueJS

Хуки создания - это самое первое, что запускается в вашей программе.

beforeCreate () - API параметров

Поскольку обработчик created - это то, что инициализирует все реактивные данные и события, beforeCreate не имеет доступа ни к каким реактивным данным и событиям компонента.

Возьмем, к примеру, следующий блок кода:

export default {
   data() { 
     return { 
       val: 'hello'    
     }
   },
   beforeCreate() {     
     console.log('Value of val is: ' + this.val)   
   }
}

Выходное значение val - undefined, потому что данные еще не инициализированы. Вы также не можете вызывать свои методы компонента в этом методе.

Если вы хотите увидеть полный список того, что доступно, я бы порекомендовал просто запустить console.log(this) , чтобы увидеть, что было инициализировано. Это полезно и во всех других ловушках при использовании API параметров.

Использование ловушки beforeCreate полезно, когда вам нужен какой-то вызов логики / API, который не нужно назначать данным. Потому что, если бы мы сейчас что-то присвоили данным, они были бы потеряны после инициализации состояния.

created () - API параметров

Теперь у нас есть доступ к данным и событиям компонента. Итак, изменив приведенный выше пример для использования created вместо beforeCreate, мы увидим, как изменится вывод.

export default {
   data() { 
     return { 
       val: 'hello'    
     }
   },
   created() {     
     console.log('Value of val is: ' + this.val)   
   }
}

Результатом этого будет Value of val is: hello, потому что мы инициализировали наши данные.

Использование созданного метода полезно при чтении / записи реактивных данных. Например, если вы хотите выполнить вызов API, а затем сохранить это значение, это место для этого.

Лучше сделать это здесь, чем в смонтированном, потому что это происходит раньше в процессе синхронной инициализации Vue, и вы выполняете чтение / запись данных все, что хотите.

А как насчет хуков создания Composition API?

Для хуков жизненного цикла Vue3, использующих Composition API, beforeCreate и created заменяются методом setup(). Это означает, что любой код, который вы поместили бы в любой из этих методов, теперь находится внутри вашего метода настройки.

Код, который мы только что написали в ловушке жизненного цикла created, будет переписан следующим образом.

import { ref } from 'vue'

export default {
   setup() {    
     const val = ref('hello') 
     console.log('Value of val is: ' + val.value)       
     return {         
       val
     }
   }
}

Монтажные крючки - доступ к DOM

Эти монтажные крючки предназначены для монтажа и рендеринга компонента. Это одни из наиболее часто используемых ловушек в проектах и ​​приложениях.

beforeMount () и onBeforeMount ()

Вызывается непосредственно перед тем, как компонент DOM будет фактически отрисован и смонтирован. На этом этапе корневой элемент еще не существует. В API параметров это можно получить с помощью this.$el. В Composition API для этого вам нужно будет использовать ref в корневом элементе.

export default {
   beforeMount() {
     console.log(this.$el)
   }
 }

Шаблон Composition с использованием ссылок будет выглядеть так.

<template>
   <div ref='root'>
     Hello World
   </div>
</template>

Затем соответствующий сценарий, чтобы попытаться получить доступ к исх.

import { ref, onBeforeMount } from 'vue'

export default {
   setup() {
      const root = ref(null) 
      onBeforeMount(() => {   
         console.log(root.value) 
      }) 
      return { 
         root
      }
    },
    beforeMount() {
      console.log(this.$el)
    }
 }

Поскольку app.$el еще не создан, результат будет неопределенным.

Хотя предпочтительно, чтобы вы использовали created() / setup() для выполнения вызовов API, на самом деле это последний шаг, который вы должны вызывать, прежде чем в нем отпадет необходимость в конце процесса, потому что он выполняется сразу после создания - они имеют доступ к одним и тем же переменным компонента.

connected () и onMounted ()

Вызывается сразу после первого рендеринга компонента. Теперь доступен элемент, обеспечивающий прямой доступ к DOM.

И снова в API параметров мы можем использовать this.$el для доступа к нашей DOM, а в Composition API нам нужно использовать ссылки для доступа к DOM в наших хуках жизненного цикла Vue.

import { ref, onMounted } from 'vue'
 

 export default {
   setup() {    /* Composition API */
 
     const root = ref(null)
 
     onMounted(() => {
       console.log(root.value)
     })
 

     return {
       root
     }
   },
   mounted() { /* Options API */
     console.log(this.$el)
   }
 }

Обновления хуков - реактивность в жизненном цикле VueJS

Обновленное событие жизненного цикла запускается всякий раз, когда изменяются реактивные данные, вызывая обновление рендеринга.

beforeUpdate () и onBeforeUpdate ()

Выполняется перед изменением данных и повторной визуализацией компонента. Это хорошее место для обновления DOM вручную до того, как произойдут какие-либо изменения. Например, вы можете удалить прослушиватели событий.

beforeUpdate может быть полезен для отслеживания количества изменений, внесенных в компонент, или даже для отслеживания действий по созданию функции «отменить».

updated () и onUpdated ()

Обновленные методы вызываются после обновления DOM. Вот начальный код, который использует как beforeUpdate, так и update.

<template>
    <div>
      <p>| edited {{ count }} times</p>
      <button @click='val = Math.random(0, 100)'>Click to Change</button>
    </div>
 </template>

С помощью любого из соответствующих скриптов.

export default {
   data() {
      return {
        val: 0
      }
   },
   beforeUpdate() {
      console.log("beforeUpdate() val: " + this.val)
   },
   updated() {
      console.log("updated() val: " + this.val
   }
 }

OR

import { ref, onBeforeUpdate, onUpdated } from 'vue'
 
 export default {
   setup () {
     const count = ref(0)
     const val = ref(0)
 
     onBeforeUpdate(() => {
       count.value++;
       console.log("beforeUpdate");
     })
 
     onUpdated(() => {
       console.log("updated() val: " + val.value)
     })
 
     return {
       count, val
     }
   }
 }

Эти методы полезны, но для многих случаев использования мы можем рассмотреть возможность использования наблюдателей для обнаружения этих изменений данных. Наблюдатели хороши тем, что они дают старое значение и новое значение измененных данных.

Другой вариант - использовать вычисленные значения для изменения состояния на основе элементов.

Крючки разрушения - Уборка вещей

Крючки для разрушения компонента используются в процессе удаления компонента и очистки всех незакрепленных концов. Это время для удаления прослушивателей событий и вещей, которые могут привести к утечкам памяти, если их не обработать должным образом.

beforeUnmount () и onBeforeUnmounted ()

Поскольку это происходит до того, как компонент начинает разрушаться, самое время выполнить большую часть, если не всю, очистку. На этом этапе ваш компонент все еще полностью функционирует, и ничего еще не было разрушено.

Пример удаления прослушивателя событий в API параметров может выглядеть так.

export default {
   mounted() {
     console.log('mount')
     window.addEventListener('resize', this.someMethod);
   },
   beforeUnmount() {
     console.log('unmount')
     window.removeEventListener('resize', this.someMethod);
   },
   methods: {
      someMethod() {
         // do smth
      }
   }
}

И это в Composition API

import { onMounted, onBeforeUnmount } from 'vue' 

 export default {
   setup () {
 
     const someMethod = () => {
       // do smth
     }
 
     onMounted(() => {
       console.log('mount')
       window.addEventListener('resize', someMethod);
     })
 
     onBeforeUnmount(() => {
       console.log('unmount')
       window.removeEventListener('resize', someMethod);
     })
 
   }
 }

Один из способов увидеть это в действии - поработать в Vite, vue-cli или в любой среде разработки, поддерживающей горячую перезагрузку. Когда ваш код обновится, некоторые из ваших компонентов отключаются и монтируются сами.

unmounted () и onUnmounted ()

На этом этапе большая часть вашего компонента и его свойств утеряна, поэтому вы мало что можете сделать. Еще раз, я бы использовал распечатку некоторых данных, чтобы увидеть, что именно еще есть, и может ли это быть полезно для вашего проекта.

import { onUnmounted } from 'vue'

export default {
  setup () { /* Composition API */

    onUnmounted(() => {
      console.log('unmounted')
    })

  },
  unmounted() { /* Options API */
    console.log('unmounted')
  }
}

Крючки активации - управление компонентами Keep-Alive

Тег keep-alive - это элемент-оболочка для динамических компонентов. Он хранит кешированную ссылку на неактивные компоненты, поэтому Vue не нужно создавать совершенно новый экземпляр каждый раз, когда изменяется динамический компонент.

Для этого конкретного случая использования Vue дает нам два крючка жизненного цикла.

Activated () и onActivated ()

Этот метод вызывается всякий раз, когда поддерживаемый динамический компонент «повторно активируется» - это означает, что теперь он является активным представлением динамического компонента.

Например, если мы используем компоненты keep-alive для управления различными представлениями вкладок, каждый раз, когда мы переключаемся между вкладками, текущая вкладка будет запускать этот активированный обработчик.

Допустим, у нас есть следующая настройка динамического компонента с использованием оболочки keep-alive.

<template>
   <div>
     <span @click='tabName = "Tab1"'>Tab 1 </span>
     <span @click='tabName = "Tab2"'>Tab 2</span>
     <keep-alive>
       <component :is='tabName' class='tab-area'/>
     </keep-alive>
   </div>
</template>

<script>
import Tab1 from './Tab1.vue'
import Tab2 from './Tab2.vue'

import { ref } from 'vue'

export default {
  components: {
    Tab1,
    Tab2
  },
  setup () { /* Composition API */
    const tabName = ref('Tab1')

    return {
      tabName
    }
  }
}
</script>

Внутри нашего Tab1.vue компонента мы можем получить доступ к нашему крючку активации следующим образом.

<template>
 <div>
 <h2>Tab 1</h2>
 <input type='text' placeholder='this content will persist!'/>
 </div>
</template>

<script>
import { onActivated } from 'vue'

export default {
 setup() {
    onActivated(() => {
       console.log('Tab 1 Activated')
    })
 }
} 
</script>

deactivated () и onDeactivated ()

Как вы можете догадаться, это вызывается, когда поддерживаемый компонент больше не является активным представлением динамического компонента.

Этот хук может быть полезен для таких случаев, как сохранение пользовательских данных, когда определенное представление теряет фокус и запуск анимации.

Мы можем поймать крючок вот так.

import { onActivated, onDeactivated } from 'vue'

export default {
  setup() {
    onActivated(() => {
       console.log('Tab 1 Activated')
    })

    onDeactivated(() => {
       console.log('Tab 1 Deactivated')
    })
  }
}

Теперь, когда мы переключаемся между вкладками - состояние каждого динамического компонента будет кэшироваться и сохраняться.

Большой!

Отладочные хуки Vue3

Vue3 дает нам два крючка, которые мы можем использовать для отладки. Они есть:

  1. onRenderTracked
  2. onRenderTriggered

Оба эти события принимают DebuggerEvent, который позволяет нам узнать, что вызывает повторный рендеринг в нашем экземпляре Vue.

export default {
    onRenderTriggered(e) {
       debugger
       // inspect which dependency is causing the component to re-render
    }
}

Заключение

Независимо от того, решите ли вы использовать Options API или Composition API, важно знать не только, какой крючок жизненного цикла использовать, но и почему вы его используете.

Для многих проблем могут работать несколько ловушек жизненного цикла. Но полезно знать, что лучше для вашего случая использования. Несмотря ни на что, вы должны просто подумать об этом и иметь вескую причину для выбора конкретного крючка жизненного цикла.

Надеюсь, это помогло вам немного больше узнать о хуках жизненного цикла и о том, как их реализовать в своих проектах.

Удачного кодирования!

Если вы хотите узнать больше о Vue 3, скачайте мою бесплатную шпаргалку по Vue 3 с такими важными знаниями, как Composition API, синтаксис шаблона Vue 3 и обработка событий.