Vue的生命周期可以分为四个阶段(实际上有11个 -- 列在最后,常用的有8个)
生命周期的“钩子函数”,表示的是生命周期的某一时刻。
一 、第一阶段是创建阶段,包括beforeCreate和created两个钩子函数。
在这个阶段,Vue会进行一些准备工作,如声明方法和生命周期钩子函数。
同时,Vue会将data数据注入并进行数据劫持。
beforeCreate(创建前):
这个时候,在实例被完成创建出来前,el和data都没有初始化,不能访问data、method,一般在这个阶段不进行操作。
created(创建后):
Vue实例中的data和methods已经被初始化,属性也已经被绑定,但是此时仍然处于虚拟DOM阶段,真正的DOM还没有生成,所以$el属性还不可用。
不过,此时已经可以调用data和methods中的数据和方法了。
因此,created钩子函数是最早可以访问和调用data和methods的阶段。通常情况下,我们会在created钩子函数中对数据进行初始化操作。
二 、第二阶段是挂载阶段,包括beforeMount和mounted两个钩子函数。
在这个阶段,Vue会查找组件的模板,并将其编译成render函数。
然后,Vue会根据render函数生成抽象语法树AST,并将其创建成虚拟DOM(VNode1)。
最后,Vue会根据虚拟DOM创建真实DOM并进行渲染。
beforeMount(挂载前):
在这个阶段,模板已经完成编译,但还没有被渲染到页面上(即虚拟DOM尚未转换为真实DOM)。此时,如果定义了el属性,el将显示在这里。
这是最后一次在渲染之前更改数据的机会,并且不会触发其他的钩子函数。通常情况下,我们可以在这里进行初始数据的获取。
mounted(挂载后):
在这个阶段,模板已经被渲染成了真实的DOM,用户可以看到已经完成渲染的页面,页面的数据也通过双向绑定显示了data中的数据。
mounted生命周期函数是实例创建期间的最后一个钩子函数。当mounted被执行完毕时,表示实例已经完全创建好了。
此时,如果没有其他操作,这个实例就会静静地存在于我们的内存中,保持静止不动。
三 、第三阶段是更新阶段,包括beforeUpdate和updated两个钩子函数。
在这个阶段,当data数据发生变化时,Vue会进入更新阶段。
Vue会根据render函数生成新的虚拟DOM(VNode2),然后使用Diff算法找出两个虚拟DOM之间的差异并进行合并,最终生成新的虚拟DOM。
最后,通过Watcher将依赖更新到真实DOM上。
beforeUpdate(更新前):
在更新前的状态(即在view层的数据变化之前),beforeUpdate钩子函数会被触发。
在重新渲染之前,Vue的虚拟DOM机制会重新构建虚拟DOM树,并利用diff算法与上一次的虚拟DOM树进行对比,然后进行重新渲染。
只有在view上的数据发生变化时,beforeUpdate和updated钩子函数才会被触发。而仅仅是data中的数据改变是无法触发这两个钩子函数的。
updated(更新后):
数据已经更改完成,dom也重新render完成。
四、第四阶段是销毁阶段,包括beforeDestroy和destroyed两个钩子函数。
在调用destroy()或路由切换时,组件会进入销毁阶段。
在这个阶段,Vue会移除Watcher,停止DOM的更新。
同时,Vue会卸载当前组件的子组件以及事件处理器。
beforeDestroy(销毁前):
在执行销毁前的操作(即在调用$destroy方法时),一般会在这里完成一些善后工作,如清除计时器、解绑非指令的事件等等。
这个时候可以对组件进行一些收尾工作,确保在组件销毁之前进行必要的清理操作,以防止潜在的内存泄漏或其他问题的发生。
destroyed(销毁后):
在组件销毁后,DOM元素仍然存在,但不再由Vue控制。在这个阶段,会进行一些操作,包括卸载watcher、解绑事件监听以及销毁子组件。
卸载watcher是为了解除对数据的监听,以防止内存泄漏。通过执行卸载watcher操作,可以释放对数据的引用,使其可以被垃圾回收。
解绑事件监听是为了防止在组件销毁后仍然存在对事件的监听,从而避免出现意外的行为或内存泄漏。
在组件销毁后,会递归地销毁所有的子组件,以释放资源并保持组件树的一致性。
至此,Vue解除了所有的束缚,释放了组件的资源,让其回归到宁静和平衡的状态。
备注(生命周期11个钩子函数):
- beforeCreate(创建前):在实例被创建之初,数据观测(data observer)和事件/watcher 事件配置之前被调用。
- created(创建后):在实例已经完成数据观测(data observer),属性和方法的运算,watcher 事件配置之后被调用。但是此时挂载阶段还未开始,$el 属性尚不可用。
- beforeMount(挂载前):在挂载开始之前被调用,相关的 render 函数首次被调用。
- mounted(挂载后):实例已经完成挂载,即模板编译成HTML并渲染到页面中。
- beforeUpdate(更新前):在数据更新之前被调用,发生在虚拟 DOM 重新渲染和打补丁之前。
- updated(更新后):在由于数据更改导致的虚拟 DOM 重新渲染和打补丁之后调用。
- activated(激活):用于 keep-alive 组件,组件被激活时调用。
- deactivated(停用):用于 keep-alive 组件,组件被停用时调用。
- beforeUnmount(卸载前):在卸载组件之前调用。
- unmounted(卸载后):在卸载组件之后调用。
- errorCaptured(错误捕获):捕获子孙组件发生的错误,统一处理错误的回调函数。