在 Vue.js 中,生命周期是指从一个 Vue 实例创建到销毁的过程。在此过程中,Vue 实例会经历一系列的事件(生命周期钩子),开发者可以通过这些钩子函数来添加自定义的操作,以便在合适的时机执行一些特定的任务。
Vue 的生命周期可以分为几个阶段:创建阶段 、挂载阶段 、更新阶段 、销毁阶段。每个阶段都有一系列的生命周期钩子函数,允许我们在不同的时刻插入代码。
1. 创建阶段
在创建阶段,Vue 实例会初始化数据、事件、生命周期钩子等。这个阶段主要涉及到 beforeCreate 和 created 两个钩子。
-
beforeCreate这是 Vue 实例创建的最早阶段,此时数据观测和事件/生命周期钩子都还没有设置。无法访问
data、computed、methods等实例属性。调用时机:实例初始化之后,数据观测和事件/生命周期钩子尚未设置之前。
javascript
beforeCreate() { console.log("beforeCreate: 数据和事件还没有初始化"); } -
created这个钩子会在实例创建完成后立即调用,此时 Vue 实例的数据已经观测(data)并且可以访问
data、computed、methods,但组件的 DOM 还未挂载,因此不能访问$el。调用时机:实例创建完成后,数据观测、事件配置完成,但尚未挂载。
javascript
created() { console.log("created: 数据已初始化,可以访问 data"); }
2. 挂载阶段
在挂载阶段,Vue 实例会将模板编译成 DOM 元素,完成对页面的渲染和挂载。此时的生命周期钩子主要是 beforeMount 和 mounted。
-
beforeMount该钩子在模板渲染之前调用,即 Vue 实例已经完成了数据和事件的初始化,但 DOM 还没有渲染出来。
调用时机 :
created钩子之后,mounted钩子之前。javascript
beforeMount() { console.log("beforeMount: 页面尚未渲染"); } -
mounted该钩子在 Vue 实例挂载到 DOM 之后立即调用,此时可以访问到
this.$el,即实际渲染的 DOM 元素。调用时机:实例挂载到 DOM 之后。
javascript
mounted() { console.log("mounted: DOM 已挂载,可以访问 $el"); }
3. 更新阶段
当数据变化时,Vue 会重新渲染组件,更新虚拟 DOM 并与真实 DOM 进行比对。这一过程会触发 beforeUpdate 和 updated 两个钩子。
-
beforeUpdate该钩子在组件数据更新之前调用,此时数据已更新,但视图尚未更新。此时可以访问到最新的数据。
调用时机:组件数据变化后,视图重新渲染前。
javascript
beforeUpdate() { console.log("beforeUpdate: 数据已更新,但视图尚未更新"); } -
updated该钩子在组件数据更新且视图重新渲染完成后调用。此时可以进行基于新 DOM 的操作。
调用时机:组件视图更新后。
javascript
updated() { console.log("updated: 视图已更新"); }
4. 销毁阶段
在销毁阶段,Vue 实例会清理定时器、移除事件监听器、销毁子组件等。生命周期钩子包括 beforeDestroy 和 destroyed。
-
beforeDestroy该钩子在 Vue 实例销毁之前调用,通常用于清理一些手动设置的资源,比如定时器、事件监听器等。
调用时机:组件销毁前。
javascript
beforeDestroy() { console.log("beforeDestroy: 组件将要销毁"); } -
destroyed该钩子在 Vue 实例销毁后调用,此时实例的数据、事件、DOM 等都已经销毁。
调用时机:组件销毁后。
javascript
destroyed() { console.log("destroyed: 组件已销毁"); }
总结 Vue 生命周期的钩子顺序
plaintext
beforeCreate // 实例刚创建,数据和事件未初始化 created // 实例创建完成,数据已初始化 beforeMount // 视图挂载前,模板尚未渲染 mounted // 视图挂载完成,DOM 已渲染 beforeUpdate // 数据更新前,视图未更新 updated // 数据更新后,视图已更新 beforeDestroy // 实例销毁前 destroyed // 实例销毁后
特殊注意事项
-
watch和computed访问时机:watch观察的数据变化会在updated钩子之前响应。computed是基于数据的缓存,在beforeUpdate钩子时,数据已经更新,因此computed属性的值已经是最新的。
-
异步更新:
- Vue 会对 DOM 更新进行异步处理,因此一些 DOM 更新相关的操作(比如访问
this.$el)会被推迟到下一个事件循环中。
- Vue 会对 DOM 更新进行异步处理,因此一些 DOM 更新相关的操作(比如访问
-
activated和deactivated:在
keep-alive包裹的组件中,会额外触发activated和deactivated钩子,用于管理组件的激活和销毁。
总结
Vue 的生命周期钩子为开发者提供了多个钩子函数,用于在组件的不同阶段插入自定义逻辑。理解生命周期钩子的调用顺序和用途,有助于编写更高效和可维护的 Vue 代码,尤其是在处理异步操作、组件初始化、销毁等任务时。