组件生命周期
理解组件的生命周期,至少有两个主要的理由:
- 遇到问题后,更容易知道从何诊断。
- 理解其他高级特性前,需要对组件生命周期有所理解。
Vue.js 3.x 生命周期图示
创建阶段#
这是生命周期的初始阶段。在这个阶段里,Vue.js 将创建组件新的实例,这包括属性的处理,比如:data,computed 属性。创建完组建后(但是在处理配置对象前),Vue.js 会调用 beforeCreate 方法。一旦 Vue.js 处理完它的配置对象(包括数据属性)后,就会调用 created 方法。
输出如下:
beforeCreate 方法被调用的时候,Vue.js 也只是才创建好了组件实例。此时,this 变量指向的就是组件本身。当 Vue.js 继续执行初始化的时候,this 会被设置 data 和 computed 属性,以及 methods。至此,创建阶段完成。
Vue.js 有一个重要特性就是反应式。当 data 属性发生变更时,变化会被传递给应用,从而触发 计算属性,数据绑定,props 的更新。所以,在创建阶段,每个 data 属性都会添加一个属性,就是 getter 和 setter。
挂载阶段#
这是组件生命周期的第二个阶段。在这里,Vue.js 会处理组件的模板,数据绑定,指令,以及其他应用特性。
如果组件需要访问 DOM,那么可以借助于 mounted 事件,它用于指示组件内容已被处理。但是需要注意的是,任何应用到 Vue.js 组件上的 HTML 属性,都会体现在模板的顶级元素上。
更新阶段#
一旦组件完成初始化并且挂载完了内容,那么就会进入更新阶段,此时 Vue.js 会相应 data 属性的变更。当一旦侦测到变更,Vue.js 就会调用 beforeUpdate 方法,而完成了更新之后(体现在 HTML 内容上的变化)就会调用 update 方法。
输出如下:
caution
在 beforeUpdate 方法调用时,组件 data 属性中的值已发生变更,只是 DOM 结构没有开始发生变化,所以 updated 提示的是 DOM 结构已完成更新。
更新合并#
在上述例子中,对数组 names 执行了多次添加操作,以及对 checked 也重新赋了值,但是只触发了一次 beforeUpdate 和 updated 方法。这就是 Vue.js 争对数据更新所做的更新合并操作,这是为了性能的提升。
tip
beforeUpdate 和 updated 方法仅在数据变更会导致 HTML 元素改变时才会触发。所以在上述例子中,如果注销了 mounted 方法中向 names 数组中添加数据的部分,即使对 checked 做了修改,也不会触发这两个方法的调用。
更新后期回调:nextTick#
Vue.js 提供了一个 Vue.nextTick 方法,它可以用于在所有变更都执行完成了之后,再执行它当中定义的任务。
输出如下:
关注数据变更:watcher#
beforeUpdate 和 update 方法会告诉你组件的 HTML 元素发生了更新,但不会告诉你哪一个属性发生了变化。特别是在当一个 data 的属性变化不会引起 HTML 变化的时候,更难知道哪些数据发生变化。如果这时候,想要接收到数据属性的变化,就需要使用到 watcher。
输出如下:
我们知道,在上面的示例中,checked 属性变化,是不会体现在 beforeUpdate 或者 updated 方法中的,但是通过 watch,我们可以精准监测属性值的前后变化。除此之外,我们要注意到 watch 中的监听方法会在 beforeUpdate 和 update 方法之前调用。
卸载阶段#
组件生命周期的最后阶段就是卸载,Vue.js 在组件即将卸载前调用 beforeUnmount 方法,在这里面,可以执行一些卸载前的操作,比如事件监听。卸载完成之后,则会调用 unmounted 方法,至此,已经移除监听器,事件处理器,以及组件的子组件。
如果取消勾选,就会看到如下输出: