一、前言
在使用 Vue 开发应用时,我们经常需要在组件加载、更新或销毁时执行一些特定逻辑,例如:
- 页面初始化时请求数据;
- 数据变化时更新 DOM 或发送埋点;
- 组件卸载时清除定时器、取消事件监听等资源释放操作。
Vue 提供了一套完整的生命周期钩子函数(Lifecycle Hooks),允许我们在组件的不同阶段插入自定义逻辑。掌握 Vue 实例的生命周期,是构建可维护、高性能 Vue 应用的关键。
本文将带你深入了解 Vue 实例(包括 Vue 2 和 Vue 3)的完整生命周期流程,并结合实际开发场景讲解每个钩子的作用和使用技巧。
二、什么是生命周期?
生命周期 是指一个 Vue 实例从被创建到最终被销毁的整个过程。在这个过程中,Vue 会自动调用一些钩子函数(Hook),我们可以利用这些钩子来插入自己的逻辑代码。
📌 生命周期本质上是一个状态机模型,不同阶段触发不同回调函数。
三、Vue 2 实例生命周期流程图概览
以下是 Vue 2 实例的生命周期流程图简要概括:
beforeCreate
↓
created
↓
beforeMount
↓
mounted
↓
beforeUpdate
↓
updated
↓
beforeDestroy
↓
destroyed
四、Vue 2 各个生命周期钩子详解
1. beforeCreate
- 触发时机 :实例刚被创建,
data
和methods
还未被初始化。 - 使用场景:极少使用,因为无法访问 data 和 methods。
- 特点:此时尚未解析选项,不能访问任何响应式数据。
javascript
beforeCreate() {
console.log('beforeCreate: 尚未访问 data');
}
2. created
- 触发时机 :实例已经创建完成,
data
和methods
已经可以访问。 - 使用场景:常用于发起异步请求(如 API 请求)、初始化数据。
- 注意:此时还没有挂载 DOM,不能操作 DOM 元素。
javascript
created() {
console.log('created: data 已初始化', this.message);
}
3. beforeMount
- 触发时机:模板编译/渲染函数已准备好,但尚未把虚拟 DOM 渲染成真实 DOM。
- 使用场景:较少使用,通常用于性能监控或预处理。
javascript
beforeMount() {
console.log('beforeMount: 模板即将渲染');
}
4. mounted
- 触发时机:模板已经成功渲染为真实 DOM,此时可以安全地操作 DOM。
- 使用场景 :最常用的钩子之一,用于:
- 初始化第三方库(如 ECharts 图表)
- 获取 DOM 节点信息
- 发送网络请求并绑定数据
- 注册事件监听
javascript
mounted() {
console.log('mounted: DOM 已渲染完毕', document.getElementById('myDiv'));
}
5. beforeUpdate
- 触发时机:响应式数据发生改变,但视图还未更新。
- 使用场景:可用于获取更新前的 DOM 状态,用于后续对比或动画控制。
javascript
beforeUpdate() {
console.log('beforeUpdate: 数据已变更,DOM 即将更新');
}
6. updated
- 触发时机:数据更新导致虚拟 DOM 重新渲染和打补丁后。
- 使用场景:适用于依赖 DOM 更新后的操作,如重新初始化插件、手动触发动画等。
- 注意:避免在此修改数据,否则可能导致死循环。
javascript
updated() {
console.log('updated: DOM 已更新');
}
7. beforeDestroy
- 触发时机:实例即将被销毁时调用。
- 使用场景 :清理操作,如:
- 移除事件监听器
- 清除定时器
- 取消长连接
- 解绑全局变量或状态
javascript
beforeDestroy() {
clearInterval(this.timer); // 假设之前设置了定时器
console.log('beforeDestroy: 正在清理资源');
}
8. destroyed
- 触发时机:实例已经被销毁,所有指令都已解绑,子组件也已被销毁。
- 使用场景:一般不做复杂操作,仅用于日志记录或调试。
javascript
destroyed() {
console.log('destroyed: 实例已销毁');
}
五、Vue 3 生命周期的变化(Composition API)
在 Vue 3 的 Composition API 写法中,生命周期钩子发生了变化:
Vue 2 钩子名 | Vue 3 Composition API |
---|---|
beforeCreate |
不再需要(setup 代替) |
created |
不再需要(setup 代替) |
beforeMount |
onBeforeMount() |
mounted |
onMounted() |
beforeUpdate |
onBeforeUpdate() |
updated |
onUpdated() |
beforeDestroy |
onBeforeUnmount() |
destroyed |
onUnmounted() |
示例(Vue 3 + Composition API):
javascript
<script setup>
import { onMounted, onUnmounted } from 'vue'
let timer = null
onMounted(() => {
console.log('组件已挂载')
timer = setInterval(() => {
console.log('每秒打印一次')
}, 1000)
})
onUnmounted(() => {
console.log('组件即将卸载')
clearInterval(timer)
})
</script>
六、常见应用场景总结
场景 | 推荐生命周期钩子 |
---|---|
初始化数据 | created / onMounted |
请求数据 | created / onMounted |
操作 DOM | mounted / onMounted |
注册/移除事件监听 | mounted + beforeDestroy / onMounted + onUnmounted |
设置定时器 | mounted / onMounted |
清理定时器、资源 | beforeDestroy / onUnmounted |
响应数据更新 | updated / onUpdated |
七、注意事项与最佳实践
- ✅ 不要在 created 中操作 DOM,因为此时 DOM 还未生成。
- ✅ 避免在 updated 中修改数据,可能造成无限循环。
- ✅ 合理释放资源,尤其是事件监听器和定时器,防止内存泄漏。
- ✅ Vue 3 推荐使用 Composition API,更符合函数式编程思想,易于复用和测试。
- ✅ 使用 computed 而不是 watch,除非你需要副作用逻辑。
八、结语
感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!