VUE生命周期渲染顺序

1,480 阅读2分钟

生命周期简绍

  • beforeCreate:在实例初始化之后,数据观测之前,data 和 $el 不可用。

  • created:在实例创建完成后被立即调用,data可用,$el不可用。

  • beforeMount:在挂载DOM开始之前被调用,data可用,$el不可用。

  • mounted:组件被调用并被挂载到实例上的回调,data 和 $el 可用。

  • beforeDestroy:实例销毁之前调用,data 和 $el 可用。

  • destroyed:Vue 实例销毁后调用,data可用,$el不可用。

  • beforeUpdate:数据更新时调用,发生在虚拟DOM打补丁前。适合在更新之前访问现有的DOM,比如移除已添加的事件监听。

  • updated:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。

  • activated:keep-alive 组件激活时调用。

  • deactivated:keep-alive 组件停用时调用。

  • errorCaptured:当捕获一个来自子孙组件的错误时被调用。此钩子可以返回 false 以阻止该错误继续向上传播。

本文主要以 beforeCreate、created、beforeMount、mounted、beforeDestroy、destroyed 这几个钩子为主,分析多组件之间生命周期的触发顺序。

单个组件

单个组件触发顺序如下:

beforeCreate
created
beforeMount
mounted
beforeDestroy
destroyed

父子关系

// page
<A></A>

// 组件A
<B></B>

// 组件B
<C></C>

触发顺序如下:

A beforeCreate
A created
A beforeMount
B beforeCreate
B created
B beforeMount
C beforeCreate
C created
C beforeMount

C mounted
B mounted
A mounted

A beforeDestroy
B beforeDestroy
C beforeDestroy

C destroyed
B destroyed
A destroyed

兄弟关系

// page
<A></A>
<B></B>
<C></C>

触发顺序如下:

A beforeCreate
A created
A beforeMount
B beforeCreate
B created
B beforeMount
C beforeCreate
C created
C beforeMount

A mounted
B mounted
C mounted

A beforeDestroy
A destroyed
B beforeDestroy
B destroyed
C beforeDestroy
C destroyed

页面之间跳转

把 A、B 组件分别挂载到两个路由下,从 A 跳转到 B 看一下生命周期是怎么触发的(或者用 v-if v-else 切换两个组件的显示)。

// page
<button @click="status = false">Btn</button>
<A v-if="status"></A>
<B v-else></B>

A beforeCreate
A created
A beforeMount
A mounted

B beforeCreate
B created
B beforeMount

A beforeDestroy
A destroyed
B mounted

这个比较有意思,为什么不是先把A销毁再加载B呢,而是B渲染完成才销毁A,主要是为了避免长时间白屏。

总结

  • 父子组件之间加载时,会先从父到子按 beforeCreate created beforeMount 触发,然后从子到父触发 mounted。

  • 父子组件之间销毁时,会先从父到子触发 beforeDestroy,再从子到父触发 destroyed。

  • 兄弟组件之间加载时,会依据组件渲染顺序从上到下按 beforeCreate created beforeMount 组件单独触发,然后按顺序触发 mounted。

  • 兄弟组件之间销毁时,依据组件渲染顺序从上到下按 beforeDestroy destroyed 触发。

  • 组件切换显示时,先执行被显示组件的 beforeCreate created beforeMount,再执行被销毁组件的 beforeDestroy destroyed,最后执行被显示组件的 mounted。(这么做是为了减少白屏时间)