1.什么是Vue生命周期?
简单来说,Vue的生命周期就是描述一个Vue组件从引入到退出的全程。
详细来说,就是一个组件从开始创建、初始化数据、编译模板、挂载DOM-渲染、更新-渲染、卸载等一些列过程。
2.Vue生命周期的执行顺序
Vue生命周期分为三大阶段,在这三大阶段中又分为若干小阶段。因此,我们可以在不同的阶段去做该阶段适合做的事。
详细执行顺序如下:
当通过new Vue()生成Vue示例对象时,生命周期钩子、事件开始初始化(beforeCreate)。接着进行数据监测和数据代理(Created),此时可以通过实例对象访问到data中的数据和methods中的方法,但DOM树还未挂载。然后Vue开始解析模板,先判断是否有el对象,无则挂载。再判断是否有模板,有则将模板转化为render函数,通过render函数去渲染创建dom树,无则编译el对象外层html作为模板,此时完成对虚拟DOM的生成(beforeMount);接着将次虚拟DOM转化为真实DOM渲染至页面,此时可进行DOM操作(mounted);当数据有被更新时,调用beforeUpdate,根据新数据生成新的虚拟DOM(diff算法对新旧DOM进行对比并操作...),最终完成页面的更新,页面和数据保持同步(updated);在实例销毁之前,data、methods等等都处于可用状态(beforeDestroy),然后清除watcher、子组件和事件监听器,组件销毁后调用(destroyed),组件确认已被销毁。
我们可以创建一个Vue实例来进行分析验证:
<body>
<div id="root" :x="n">
<h2 style="color:#42b883">Vue的生命周期</h2>
<h3> 当前n的值是:{{n}}</h3>
<button @click="add">点我n+1</button>
<button @click="bye">点我销毁vm</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
const vm = new Vue({
el: "#root",
// template: `
// <div>
// <h2> 当前n的值是:{{n}}</h2>
// <button @click="n++">点我n+1</button>
// </div>`,
data: {
n: 1
},
beforeCreate() {
console.log("%c%s", "color:red", '-------beforeCreate-------')
console.log('$el:' + this.$el)
console.log('$data:' + this.$data)
},
created() {
console.log("%c%s", "color:red", '-------created-------')
console.log('$el:' + this.$el)
console.log('$data:' + this.$data)
},
beforeMount() {
console.log("%c%s", "color:red", '-------beforeMount-------')
console.log('$el:' + this.$el)
console.dir(this.$el)
console.log('$data:' + this.$data)
},
mounted() {
console.log("%c%s", "color:red", '-------mounted-------')
console.log('$el:' + this.$el)
console.dir(this.$el)
console.log('$data:' + this.$data)
console.dir(this.$data)
},
beforeUpdate() {
console.log("%c%s", "color:red", '-------beforeUpdate-------')
console.log('$el:' + this.$el)
console.dir(this.$el)
console.log('$data:' + this.$data)
console.dir(this.$data)
},
updated() {
console.log("%c%s", "color:red", '-------updated-------')
console.log('$el:' + this.$el)
console.dir(this.$el)
console.log('$data:' + this.$data)
console.dir(this.$data)
},
beforeDestroy() {
console.log("%c%s", "color:red", '-------beforeDestroy-------')
console.log('$el:' + this.$el)
console.dir(this.$el)
console.log('$data:' + this.$data)
console.dir(this.$data)
},
destroyed() {
console.log("%c%s", "color:red", '-------destroyed-------')
console.log('$el:' + this.$el)
console.dir(this.$el)
console.log('$data:' + this.$data)
console.dir(this.$data)
},
methods: {
bye() {
console.log('bye')
this.$destroy()
},
add() {
this.n++
}
},
})
</script>
</body>
挂载阶段
我们可以看到,当页面一加载时,触发了beforeCreate , created , beforeMount ,mounted 这几个钩子。
最先进入beforeCreate,此时我们打印的el,data均为undefined。
接着进入created,此时el仍拿不到,但data已经加载进来了。
在beforeMount时,此时已经生成虚拟DOM,但还未转化成真实DOM
mounted挂载结束,也就是虚拟DOM已经转化为真实DOM插入页面
更新阶段
我们点击n+1,可以看到:
进入更新阶段,触发beforeUpdate, updated这两个生命钩子
销毁阶段
点击销毁vm:
beforeDestroy,在销毁之前,el、data都是如同挂载之后的阶段一样,都是可以打印出来的。
destroyed完成销毁时,组件仍会打印未销毁状态时的el、data,但其定格未销毁时的最终形态,所有操作均无效。
生命周期的每个阶段适合做什么?
beforeCreate: 在Vue创建之前,data、computed、watch、methods上的方法和数据均不能访问,可以添加loading事件。。
created: 在Vue实例创建完毕状态,我们可以去访问data、computed、watch、methods上的方法和数据,但现在还没有将虚拟Dom挂载到真实Dom上,所以我们在此时访问不到我们的Dom元素。如果非要想与 Dom 进行交互,可以通过 vm.$nextTick 来访问 Dom。
我们在此时可以进行一些简单的Ajax,并可以对页面进行初始化之类的操作。
beforeMount: 它是在挂载之前被调用的,会在此时去找到虚拟Dom,并将其编译成Render。
mounted: 虚拟Dom已经被挂载到真实Dom上,此时我们可以获取Dom节点,$ref在此时也是可以访问的。
发送ajax请求、启动定时器、绑定自定义事件、订阅消息等(初始化操作)。
beforeUpdate: 响应式数据更新的时候会被调用,beforeupdate的阶段虚拟Dom还没更新,所以在此时依旧可以访问现有的Dom。
我们可以在此时访问现有的Dom,手动移除一些添加的监听事件。
updated: 此时补丁已经打完了,Dom已经更新完毕,可以执行一些依赖新Dom的操作。
但还是不建议在此时进行数据操作,避免进入死循环。
beforeDestroy: 在Vue实例销毁之前被调用,在此时我们的实例还未被销毁。
在此时可以做一些操作,比如销毁定时器,解绑全局事件,销毁插件对象等。
Vue3的生命周期
-
Vue3.0中可以继续使用Vue2.x中的生命周期钩子,但有有两个被更名:
beforeDestroy改名为beforeUnmountdestroyed改名为unmounted
可以直接已配置项的形式使用生命周期钩子,也可以使用组合式API的形式使用,尽量统一
一般来说,组合式API里的钩子会比配置项的钩子先执行,组合式API的钩子名字有变化
-
Vue3.0也提供了 Composition API 形式的生命周期钩子,与Vue2.x中钩子对应关系如下:
beforeCreate===>setup()created===>setup()beforeMount===>onBeforeMountmounted===>onMountedbeforeUpdate===>onBeforeUpdateupdated===>onUpdatedbeforeUnmount===>onBeforeUnmountunmounted===>onUnmounted