так называемыйФункция хука жизненного цикла(упоминается какфункция жизненного цикла), ссылаясь на компонентСоздайте,возобновить,разрушатьФункция, которая запускается тремя этапами для выполнения. В соответствии с функцией ловушки, запускаемой на каждом этапе, мы можем выполнять некоторые операции соответственно, такие как получение данных внутреннего интерфейса, прослушивание событий, выполнение событий, выполнение таймеров, удаление событий, очистка таймеров и так далее.
В соответствии с вышеуказанными тремя этапами жизненный цикл можно резюмировать следующим образом:
-
период реализации
создание компонента
-
Существование
обновление компонента
-
Срок уничтожения
разрушение компонента
Последующие действия объяснят функции жизненного цикла в соответствии с этими тремя циклами.
Для простоты понимания яjsrun.netПримеры написаны выше. (Веб-сайт, похожий на jsfiddle, внутренний jsfiddle заблокирован)
Диаграмма жизненного цикла
Сначала посмотрите на диаграмму жизненного цикла официального сайта, функции жизненного цикла здесь все для браузерной стороны, а серверная сторона в настоящее время поддерживает толькоbeforeCreateа такжеcreatedЭти две функции жизненного цикла.
На официальном сайте нетrender,renderErrorФункции обобщаются как функции-ловушки жизненного цикла.
вHas "el" optionСравнение выглядит следующим образом:
есть эль
// 有el属性的情况下
new Vue({
el: "#app",
beforeCreate: function() {
console.log("调用了beforeCreate");
},
created: function() {
console.log("调用了created");
},
beforeMount: function() {
console.log("调用了beforeMount");
},
mounted: function() {
console.log("调用了mounted");
}
});
// 输出结果
// 调用了beforeCreate
// 调用了created
// 调用了beforeMount
// 调用了mounted
нет эль
// 有el属性的情况下
const vm new Vue({
beforeCreate: function() {
console.log("调用了beforeCreate");
},
created: function() {
console.log("调用了created");
},
beforeMount: function() {
console.log("调用了beforeMount");
},
mounted: function() {
console.log("调用了mounted");
}
});
// 输出结果
// 调用了beforeCreate
// 调用了created
Когда нет эл, если нужно монтировать, то можно справиться так:vm.$mount('#app'). Эффект тот же, разницы по сути нет, но использование более гибкое.
период реализации
Период создания включает в себя следующие функции жизненного цикла (порядок выполнения сверху вниз):
- beforeCreate
- created
- beforeMount
- mouted
вbeforeCreateа такжеcreatedсработает в серединеrenderфункция, если есть шаблон, он будет преобразован в функцию рендеринга для рендеринга. (Конечно, если компонент определяет функцию рендеринга, то функция рендеринга имеет более высокий приоритет)
Подробный пример см.jsrun.net/LZyKp/edit
// 输出请看 右下角 Console 命令行工具
new Vue({
el: '#dynamic-component-demo',
data: {
num: 2,
},
beforeCreate(){
console.log("beforeCreate",this.num,this.a);
// 输出为 befoerCreate,,
// this.num 数据还没监测,this.a 方法未绑定
},
created(){
console.log("created",this.num,this.a,this.$el);
// 输出为 created, 2, function () { [native code] }
},
beforeMount(){
console.log(this.$el.innerText);
// 输出 {{ num }},还是原来的 DOM 内容
},
mounted(){
console.log(this.$el.innerText);
// 输出 2,已经是 vue 渲染的 DOM 内容
},
methods: {
a(){}
}
})
beforeCreate
После инициализации экземпляра перед вызовом вызывается наблюдатель данных и конфигурация события/наблюдателя.
created
Вызывается сразу после завершения создания экземпляра. На этом этапе экземпляр завершил следующую настройку: наблюдатель данных, работа со свойствами и методами и обратный вызов событий наблюдения/события. Однако этап монтирования еще не начался,$elСвойства в настоящее время не видны.
beforeMount
Вызывается перед началом монтирования: актуальноrenderФункция вызывается впервые.$elСвойство уже видно, но это все еще исходный DOM, а не вновь созданный.
mounted
elВновь созданныйvm.$elЗамените и вызовите хук после установки на экземпляр. Если корневой экземпляр монтирует внутридокументный элемент, когдаmountedкогда звонятvm.$elТакже в документации.
Уведомлениеmounted Не будетОбещают, что все подкомпоненты тоже монтируются вместе. Если вы хотите дождаться рендеринга всего представления, вы можете использоватьvm.$nextTickзаменятьmounted:
mounted: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been rendered
})
}
Существование
Период существования включает в себя следующие функции жизненного цикла:
- beforeUpdate
- updated
Vue необходимо изменить данные, чтобы вызвать повторный рендеринг компонента, а затем запустить указанную выше функцию привязки времени жизни. вbeforeUpdateа такжеupdatedсработает в серединеrenderфункция.
см. примерjsrun.net/8ZyKp/edit.
// 需要点击更新按钮
// 连续点击更新按钮,都会是 2 秒后不点击更新才会输出 “2 秒没更新了”
// 输出请看 右下角 Console 命令行工具
new Vue({
el: '#dynamic-component-demo',
data: {
num: 2,
},
beforeUpdate(){
clearTimeout(this.clearTimeout);
this.clearTimeout = setTimeout(function(){
console.log("2 秒没更新了");
},2000);
console.log("beforeUpdate",this.num,this.$el.innerText);
// 第一次点击更新,输出为 beforeUpdate,3,点击更新 2
},
updated(){
console.log("updated",this.num,this.$el.innerText);
// 第一次点击更新,输出为 updated,3,点击更新 3
},
methods: {
updateComponent(){
this.num++;
}
}
})
beforeUpdate
Когда данные обновляются, он вызывается перед изменением виртуального DOM. Подходит для доступа к существующему DOM перед обновлением, например, при ручном удалении добавленного прослушивателя событий.
Пожалуйста, не меняйте состояние этой функции, иначе она вызовет бесконечный цикл.
updated
Вызывается после обновления данных и изменения виртуального DOM.
При вызове этого хука DOM компонента обновляется, поэтому теперь вы можете выполнять операции, зависящие от DOM. Однако в большинстве случаев следует избегать изменения состояния в течение этого времени. Если вы хотите, чтобы состояние изменилось соответствующим образом, обычно лучше использоватьвычисляемое свойствоилиwatcherвместо.
Как смонтированный,updated Не будетОбещает, что все дочерние компоненты тоже перерисовываются вместе. Если вы хотите подождать, пока весь вид не будет перерисован, вы можете использоватьvm.$nextTickзаменятьupdated:
updated: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been re-rendered
})
}
Пожалуйста, не меняйте состояние этой функции, иначе она вызовет бесконечный цикл.
Срок уничтожения
Период уничтожения включает в себя следующие функции жизненного цикла:
- beforeDestroy
- destroyed
см. примерjsrun.net/QZyKp/edit.
// 切换 tab,看右下角 console 输出
Vue.component('tab-home', {
template: '<div>Home component</div>',
beforeDestroy(){
console.log("tab-home","beforeDestroy");
},
destroyed(){
console.log("tab-home","destroyed");
},
})
Vue.component('tab-posts', {
template: '<div>Posts component</div>',
beforeDestroy(){
console.log("tab-posts","beforeDestroy");
},
destroyed(){
console.log("tab-posts","destroyed");
},
})
Vue.component('tab-archive', {
template: '<div>Archive component</div>',
beforeDestroy(){
console.log("tab-archive","beforeDestroy");
},
destroyed(){
console.log("tab-archive","destroyed");
},
})
new Vue({
el: '#dynamic-component-demo',
data: {
currentTab: 'Home',
tabs: ['Home', 'Posts', 'Archive']
},
computed: {
currentTabComponent: function () {
return 'tab-' + this.currentTab.toLowerCase()
}
}
})
beforeDestroy
Вызывается перед уничтожением экземпляра, на этом этапе экземпляр все еще полностью доступен. Обычно удаляйте прослушиватели событий, таймеры и т. д., чтобы избежать утечек памяти.
destroyed
Вызывается после уничтожения экземпляра Vue. После вызова все, на что указывает экземпляр Vue, будет развязано, все прослушиватели событий будут удалены, а все дочерние экземпляры уничтожены.
Поэтому, если вам нужно использовать привязки, указанные экземпляром Vue, вам нужно использовать их в beforeDestroy. Таким образом, то, что может сделать функция destroy, может быть сделано и в beforeDestroy, поэтому нет необходимости иметь дело с этим в функции destroy.
Другие менее часто используемые функции жизненного цикла
-
activated
Вызывается при активации компонента, вы можете обратиться кКомпоненты сборки - keep-alive
-
deactivated
Вызывается, когда компонент отключен, вы можете обратиться кКомпоненты сборки - keep-alive
-
errorCaptured
Пожалуйста, смотрите этот жизненный крючок для деталейОфициальный сайт, новое в версии 2.5.0, вызывается при обнаружении ошибки от компонента-потомка.
Будьте осторожны
Пожалуйста, не используйте стрелочные функции ES6 для функций жизненного цикла, иначе возникнут проблемы с этим указанием.
Пожалуйста, посмотрите этот примерjsrun.net/cZyKp/edit.
// 输出请看 右下角 Console 命令行工具
new Vue({
el: '#dynamic-component-demo',
data: {
num: 2,
},
created: ()=>{
console.log("created",this);
// 输出为 created,[object Window]
// this 指向不是 Vue 实例而是父级 this
}
})
дивергентное мышление
Поскольку каждый компонент имеет жизненный цикл, в чем разница в порядке выполнения между компонентами «родитель-потомок» и «родственными» компонентами?
Тогда вам сначала нужно знатьtemplateКогда он преобразуется в виртуальный DOM, а когда создается виртуальный DOM, а затем монтируется в реальный DOM.
Я не буду здесь подробно объяснять принцип vue, но примерно пойму процесс перехода от шаблона к виртуальному DOM:
template -> AST 树 -> render 函数
На самом деле, мы фокусируемся на функции рендеринга, вы можете понятьсреда выполнения только для компилятора. Виртуальный дом формируется в функции рендеринга. Если вы использовали JSX, вы можете просто поставить JSX, понятый как один виртуальный DOM. Конечно, функция Render будет выполнена для монтирования реальной логики DOM.
Монтирование в любом случае должно выполняться в конце, а монтирование виртуального DOM унифицировано корневым компонентом, поэтому логи, выдаваемые монтируемой функцией всех компонентов, должны быть связаны между собой, и то же самое верно для update.
Порядок выполнения функции жизненного цикла родительско-дочернего компонента
Функция рендеринга — это разделительная линия между функциями жизненного цикла родительско-дочерних компонентов.
И порядок функции рендеринга следующий.
Период создания:beforeMount -> render -> mounted
Срок существования:beforeUpdate -> render -> updated
Подробности смотрите в онлайн-примере.jsrun.net/vhyKp/edit.
Порядок выполнения жизненного цикла родственных компонентов
Подробности смотрите в онлайн-примере.jsrun.net/NhyKp/edit.