Жизненный цикл Vue

Vue.js

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

Полный жизненный цикл vue будет проходить через следующие функции ловушек.

  • beforeCreate --- перед созданием
  • создано --- создано завершено
  • beforeMount --- перед монтированием
  • смонтирован --- монтирование завершено
  • beforeUpdate --- перед обновлением
  • обновлено --- обновление завершено
  • beforeDestroy --- перед уничтожением
  • уничтожен --- уничтожение завершено

Ситуация печати каждой функции хука под хромированной консолью

Ниже приводится пошаговая интерпретация шагов каждой функции ловушки.

beforeCreate -> created

  • Инициализировать экземпляр vue для наблюдения за данными

created

  • Полное наблюдение за данными, работа со свойствами и методами, а также настройка обратных вызовов событий наблюдения и события.
  • Вы можете вызывать методы в методах, получать доступ к данным данных и изменять их для запуска адаптивного рендеринга, а также выполнять расчет данных с помощью вычислений и просмотра.
  • На данный момент vm.$el не создан
  • Как правило, запросы ajax выполняются в созданных

created -> beforeMount

  • Определите, существует ли опция el, если нет, остановите компиляцию и продолжайте компиляцию до тех пор, пока не будет вызвана vm.$mount(el)
  • Если есть EL, определяется, есть ли шаблон, если есть, шаблон компилируется в функцию рендеринга, если нет, напрямую компилируется внешний HTML, соответствующий EL.
  • Если функция рендеринга существует, она сначала компилируется
  • В этом процессе vm.el создается как элемент DOM, соответствующий параметру el, поэтому в beforeMount с помощью vm.el получается HTML-код, который монтирует DOM.

Приоритет: рендеринг > шаблон > externalHTML

beforeMount

  • vm.el доступен на данном этапе
  • На данном этапе, несмотря на то, что vm.el завершил инициализацию DOM, он не подключен к опции el.

beforeMount -> mounted

  • На этом этапе монтируется vm.el, и DOM, сгенерированный vm.$el, заменяет DOM*, соответствующий опции el.

mounted

vm.el завершил монтирование и рендеринг DOM, в этот момент напечатайте vm.$el и обнаружите, что предыдущая точка монтирования и содержимое были заменены новым DOM.

Подтвердите это на примере

<div id="app">
    <h1 ref="h1" id="h1">{{message}}</h1>
    <button @click="changeMsg">change</button>
 </div>
 
 var vm = new Vue({
    el: '#app',
    data: {
      message: 'Vue的生命周期'
    },
    template: '<h2 id="h2">{{message}}</h2>',
    beforeMount: function() {
      console.group('------beforeMount 挂载前------');
      console.log(this.$el);
      console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化  
      console.log("%c%s", "color:red","message: " + this.message); //已被初始化  
      let h1 = document.getElementById('h1')
      let h2 = document.getElementById('h2')
      console.log('h1:',h1)
      console.log('h2:',h2)
    },
    mounted: function() {
      console.group('------mounted 挂载完成------');
      console.log(this.$el);
      console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化
      console.log("%c%s", "color:red","message: " + this.message); //已被初始化 
      let h1 = document.getElementById('h1')
      let h2 = document.getElementById('h2')
      console.log('h1:',h1)
      console.log('h2:',h2)
    },
}

  • Видно, что перед монтированием исходный el и виртуальный DOM существуют, а шаблон не скомпилирован, поэтому h2 выводит null
  • После монтирования vm.$el завершает замену el и рендеринг dom, поэтому h2 печатает шаблон после монтирования и рендеринга, а el заменяется, поэтому h1 печатается как null

beforeUpdate

Когда данные, отображаемые в шаблоне, обновляются, запускается метод beforeUpdate.

  • Обновленные данные должны быть отрисованы на шаблоне (один из el, template, render)
  • На данный момент слой просмотра не обновлен.
  • Метод обновления может быть запущен только после завершения монтирования (поскольку рендеринг шаблона завершается после завершения монтирования, а обновление — это обновление и повторный рендеринг данных шаблона)
  • Если данные снова будут изменены в beforeUpdate, метод обновления не будет запущен снова.

updated

  • Завершите обновление слоя представления
  • Если данные снова будут изменены в обновлении, метод обновления (beforeUpdate, updated) будет запущен снова.
  • Когда данные изменяются, функция рендеринга используется для создания VNode, patchVNode используется для сравнения изменений до и после, а алгоритм diff выполняет такие операции, как обновление, добавление и удаление для создания реальных узлов DOM.

нормальная работа обновления

beforeUpdate: function () {
    console.group('beforeUpdate 更新前===============》');
    console.log("%c%s", "color:red","message: " + this.message); 
    console.log(this.$refs.h1.innerHTML)
},
updated: function () {
    console.group('updated 更新完成===============》');
    console.log("%c%s", "color:red","message: " + this.message); 
    console.log(this.$refs.h1.innerHTML)
},

  • Обновление слоя представления не было завершено в beforeUpdate, и innerHTML, напечатанный на этом этапе, все еще является данными до модификации.
  • Обновление слоя представления завершено при обновлении, а напечатанный innerHTML - это измененные данные.
  • Данные данных не могут быть выведены напрямую, данные, выводимые консолью, представляют собой обновленные данные слоя представления, которые можно изменить на innerHTML для проверки.

Изменить данные в обновленном

beforeUpdate: function () {
    console.group('beforeUpdate 更新前===============》');
    console.log("%c%s", "color:red","message: " + this.message); 
    console.log(this.$refs.h1.innerHTML)
},
updated: function () {
    console.group('updated 更新完成===============》');
    console.log("%c%s", "color:red","message: " + this.message); 
    console.log(this.$refs.h1.innerHTML)
    this.message = 'updated2'
},

  • При обновлении завершается обновление данных и рендеринг слоя представления, если данные изменены, метод обновления будет запущен снова.

beforeDestroy

  • Вызывается перед уничтожением экземпляра, пока экземпляр все еще доступен

destroyed

  • Вызывается после уничтожения экземпляра
  • Полностью уничтожает экземпляр. Очистите его соединения с другими экземплярами и отмените привязку всех его директив и прослушивателей событий.
  • Объект Watcher высвобождается из своего Dep
  • Он не очищает DOM, он просто уничтожает экземпляр

  • Когда beforeDestroy экземпляр не уничтожается, доступ к DOM можно получить через this.$refs
  • При уничтожении экземпляр уничтожается, и доступ через this.$refs равен нулю.