![Vue.js从入门到项目实践(超值版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/987/44509987/b_44509987.jpg)
2.4 实例的生命周期
![](https://epubservercos.yuewen.com/CC45E5/23721548909464406/epubprivate/OEBPS/Images/Figure-P34_2349.jpg?sign=1738869192-rnE4v34L5vgAjtAOwItEeqiFfv1CaKbh-0-5634d290a70757a17ac8609ebaacbac2)
本节将介绍Vue实例从创建、运行到销毁的整个过程。在Vue实例的创建、运行、销毁期间,总是伴随着各种各样的事件,这些事件统称为“生命周期”。下面通过案例对生命周期进行详解。
Vue实例的生命周期代码如下:
![](https://epubservercos.yuewen.com/CC45E5/23721548909464406/epubprivate/OEBPS/Images/Figure-P34_52935.jpg?sign=1738869192-5VpJC0jZlhUTpvtxTQ1jFacrFPvr9T07-0-c090044088ee112c05274525b1a45fe0)
![](https://epubservercos.yuewen.com/CC45E5/23721548909464406/epubprivate/OEBPS/Images/Figure-P35_52936.jpg?sign=1738869192-JA3FZ7UDspj08l75iieJ2IGHjXgsT6RD-0-303a22cfd24623d3f179afba5e3c42ea)
1.beforeCreate()
beforeCreate()在实例初始化后,数据观测(data observer)和event/watcher事件配置前被调用。
提示:这个时候this还不能使用,data中的数据、methods中的方法,以及watcher中的事件都不能获得,值为undefined。
代码如下:
![](https://epubservercos.yuewen.com/CC45E5/23721548909464406/epubprivate/OEBPS/Images/Figure-P36_52938.jpg?sign=1738869192-yEuZquVcl49IzCXkJRrnxi1fWo23VPtV-0-7f0341abafd6584b7d63bd8629b947fc)
运行的结果如图2-14所示。
![](https://epubservercos.yuewen.com/CC45E5/23721548909464406/epubprivate/OEBPS/Images/Figure-P36_52939.jpg?sign=1738869192-R3NoPU5zgtu5IbxI0TJcxrawHGSuA7nF-0-59c72aa2a35714038a27880b80d15143)
图2-14 beforeCreate()运行结果
2.created()
created()在实例已经创建完成后被调用。在这一步,实例已完成以下配置:数据观测(data observer)、属性和方法的运算及watch/event事件回调。挂载阶段还没开始的$el属性为不可见,值为undefined。
提示:这个时候可以操作Vue中的数据和方法,但是还不能对DOM节点进行操作。
created(){ console.group('created 创建完毕状态'); console.log("%c%s", "color:red", "el : "+this.$el); //undefined console.log("%c%s", "color:red", "data : "+this.$data); //[object Object] console.log("%c%s", "color:red", "message : "+this.message); //值为Hello World!!! },
运行的结果图如图2-15所示。
![](https://epubservercos.yuewen.com/CC45E5/23721548909464406/epubprivate/OEBPS/Images/Figure-P37_52941.jpg?sign=1738869192-0MaXJ02zPq59U1t16lqJK5O4PtcbjyEe-0-ec36efea3b18af7e710149deddb93427)
图2-15 created()运行结果
3.beforeMount()
beforeMount()在挂载开始前被调用,相关的render函数首次被调用。
提示:这个时候,$el属性已存在,是虚拟DOM,只是数据未挂载到模板中。
beforeMount(){ console.group('beforeMount 挂载前状态'); console.log("%c%s", "color:red", "el : "+this.$el); //[object HTMLDivElement] console.log(this.$el); console.log("%c%s", "color:red", "data : "+this.$data); //[object Object] console.log("%c%s", "color:red", "message : "+this.message); //值为Hello World!!! },
运行的结果如图2-16所示。
![](https://epubservercos.yuewen.com/CC45E5/23721548909464406/epubprivate/OEBPS/Images/Figure-P37_52943.jpg?sign=1738869192-dEFTnupO5NyujatOD2JzypeR5InHTNj0-0-a688acaa966228f81151378d0aca7313)
图2-16 beforeMount()运行结果
4.mounted()
el被新创建的vm.$el替换,并挂载到实例上后调用该钩子函数。如果root实例挂载了一个文档内元素,当mounted()被调用时vm.$el也在文档内。mounted()不会承诺所有的子组件都一起被挂载。如果想要整个视图都渲染完毕,可以使用vm.$nextTick替换mounted()。
提示:挂载完毕,这时DOM节点被渲染到文档内,DOM操作在此时能正常进行。
mounted(){ console.group('mounted 挂载结束状态'); console.log("%c%s", "color:red", "el : "+this.$el); //[object HTMLDivElement] console.log(this.$el); console.log("%c%s", "color:red", "data : "+this.$data); //[object Object] console.log("%c%s", "color:red", "message : "+this.message); //值为Hello World!!! },
运行的结果如图2-17所示。
![](https://epubservercos.yuewen.com/CC45E5/23721548909464406/epubprivate/OEBPS/Images/Figure-P38_52946.jpg?sign=1738869192-g6MfVOtYdPYJIAWcaqjIiIsXByEGtW5b-0-b9afd99cb898d9a07e8733fa7ce99ae7)
图2-17 mounted()运行结果
5.beforeUpdate()
beforeUpdate()在数据更新时被调用,发生在虚拟DOM打补丁前。这里适合在更新前访问现有的DOM,例如手动移除已添加的事件监听器。
提示:beforeUpdate()是指View层的数据变化前,而不是data中的数据改变前被触发。因为Vue是由数据驱动的。
beforeUpdate(){ console.group('beforeUpdate 更新前状态'); console.log("%c%s", "color:red", "el : "+this.$el); //[object HTMLDivElement] console.log(this.$el); console.log(this.$el.innerHTML); console.log("%c%s", "color:red", "data : "+this.$data); //[object Object] console.log("%c%s", "color:red", "message : "+this.message); //值为Hello Vue!!! },
运行的结果如图2-18所示。
![](https://epubservercos.yuewen.com/CC45E5/23721548909464406/epubprivate/OEBPS/Images/Figure-P38_52948.jpg?sign=1738869192-fSHKYQ8Kass95sbl9Qru4oUWX4SkpXBN-0-37fb067b6f86e242a6e1f25e38c5fcff)
图2-18 beforeUpdate()运行后修改message值为Hello Vue!!!
6.updated()
由于数据的更改导致虚拟DOM重新渲染和打补丁,在这以后会调用该钩子函数。当该钩子函数被调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而,在大多数情况下,应该避免在此期间更改状态。如果要改变相应状态,最好使用计算属性或watcher取而代之。updated()不会承诺所有的子组件都一起被重绘。如果希望等到整个视图都重绘完毕,可以用vm.$nextTick替换掉updated()。
提示:View层的数据更新后,data中的数据同beforeUpdate(),都是更新完以后的。
updated(){ console.group('updated 更新完成状态'); console.log("%c%s", "color:red", "el : "+this.$el); //[object HTMLDivElement] console.log(this.$el); console.log(this.$el.innerHTML); console.log("%c%s", "color:red", "data : "+this.$data); //[object Object] console.log("%c%s", "color:red", "message : "+this.message); //值为Hello Vue!!! },
运行的结果如图2-19所示。
![](https://epubservercos.yuewen.com/CC45E5/23721548909464406/epubprivate/OEBPS/Images/Figure-P39_52950.jpg?sign=1738869192-uTH52gPt0uH4uNOYBWq6td3fZcqZnQxg-0-c7cedd8b1617334c841f2bb29951b8f8)
图2-19 updated()运行结果
提示:从上面可以看到,beforeUpdate()和updated()钩子函数中的$el一样,因为beforeUpdate()应该指向虚拟DOM,所以$el才会相同,而DOM中的真正内容是不一样的。
7.beforeDestroy()
beforeDestroy()在实例销毁前被调用。在这一步,实例仍然完全可用。
提示:执行vm.$destroy()触发beforeDestroy()和destoryed()钩子函数。
beforeDestroy(){ console.group('beforeDestroy 销毁前状态'); console.log("%c%s", "color:red", "el : "+this.$el); //[object HTMLDivElement] console.log(this.$el); console.log("%c%s", "color:red", "data : "+this.$data); //[object Object] console.log("%c%s", "color:red", "message : "+this.message); //值为Hello Vue!!! },
8.destroyed()
destroyed()在Vue实例销毁后被调用。调用后,Vue实例指向的所有部分都会被解绑定、所有的事件监听器会被移除、所有的子实例也会被销毁。
提示:执行destroyed ()后,对data的改变不会再触发生命周期函数,此时的Vue实例已经解除了事件监听及与DOM的绑定,但是DOM结构依然存在。
destroyed(){ console.group('destroyed 销毁完成状态'); console.log("%c%s", "color:red", "el : "+this.$el); //[object HTMLDivElement] console.log(this.$el); console.log("%c%s", "color:red", "data : "+this.$data); //[object Object] console.log("%c%s", "color:red", "message : "+this.message); //值为Hello Vue!!! },