![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=1738870035-fzk44fSQ1e9xKjVpfXxwEzBhyjaosKeo-0-7bff48e508d627da781a067a918346df)
本节将介绍Vue实例从创建、运行到销毁的整个过程。在Vue实例的创建、运行、销毁期间,总是伴随着各种各样的事件,这些事件统称为“生命周期”。下面通过案例对生命周期进行详解。
Vue实例的生命周期代码如下:
![](https://epubservercos.yuewen.com/CC45E5/23721548909464406/epubprivate/OEBPS/Images/Figure-P34_52935.jpg?sign=1738870035-X28bpRFwBwDnZVfPcVUpKCfYkbjqHNOt-0-783ace764f3ee9d834a41437c8ae690a)
![](https://epubservercos.yuewen.com/CC45E5/23721548909464406/epubprivate/OEBPS/Images/Figure-P35_52936.jpg?sign=1738870035-C28EjBXc8yIO3lyzORl3I1UDxWmJEC03-0-30d8cf6b44b9bf32b388158686dde44e)
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=1738870035-MVvaG0yV4UBB2tclHd07p75RdabBrbAr-0-9b7d03863f06ab6b5b98232aae86039d)
运行的结果如图2-14所示。
![](https://epubservercos.yuewen.com/CC45E5/23721548909464406/epubprivate/OEBPS/Images/Figure-P36_52939.jpg?sign=1738870035-NZaIIJSempAqFzdqEa2y9jNtOXE90lOt-0-43b71ece562a29e2b0ccc61f3bea6e85)
图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=1738870035-yDh0ezVIdYxhl4wqm9KnTOqioD26RB5C-0-0e641e22ab6b10e9340d3f5401f8b38a)
图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=1738870035-rkJPsyuY6BeOZ9izQVxIVKVWkA9EURxR-0-541e0a468737a87a5459d7738c8424c2)
图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=1738870035-NjUkBNZ594aU3yVq1gRJ4HYRbYW79jQq-0-fd908e68bc6b14b0058934545435cd28)
图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=1738870035-f030t9xL7WFtwLVdz1KlOch759mzdY9H-0-84a919dc0fc92c5fb75a9f774345aa54)
图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=1738870035-KQzy2cSp8BpsMrD15E93khU4LGNdY8Um-0-626070ccbb3e316932a94e6cce9ed6a4)
图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!!! },