Vue生命周期
Vue组件的生命周期描述了组件从创建、挂载、更新到销毁的完整过程。每个阶段都提供了对应的生命周期钩子函数,允许开发者在特定时机执行自定义逻辑。以下是Vue 2.x和Vue 3.x的核心生命周期阶段及钩子函数(Vue 3兼容Composition API和Options API)。
Vue生命周期流程图
创建阶段 → 挂载阶段 → 更新阶段 → 销毁阶段
Vue 2.x生命周期钩子
阶段 | 钩子函数 | 触发时机 | 典型应用场景 |
---|---|---|---|
创建阶段 | beforeCreate | 组件实例刚创建,数据观测和事件配置前。 | 初始化非响应式变量(如非data 的变量)。 |
created | 组件实例创建完成,数据观测、计算属性、方法等已配置,但DOM未生成。 | 发起异步请求、初始化数据。 | |
挂载阶段 | beforeMount | 模板编译完成,虚拟DOM已生成,但未挂载到页面。 | 极少使用。 |
mounted | 组件挂载到DOM后调用,可访问DOM元素。 | 操作DOM、初始化第三方库(如图表库)。 | |
更新阶段 | beforeUpdate | 数据变化后,虚拟DOM重新渲染前。 | 获取更新前的DOM状态。 |
updated | 数据变化导致虚拟DOM重新渲染并更新到真实DOM后。 | 依赖更新后DOM的操作(如调整元素尺寸)。 | |
销毁阶段 | beforeDestroy | 组件销毁前调用(Vue 3中改为beforeUnmount )。 | 清理定时器、取消事件监听、释放资源。 |
destroyed | 组件销毁后调用(Vue 3中改为unmounted )。 | 极少使用(组件已完全移除)。 |
Vue 3.x生命周期变化
-
Options API兼容
Vue 3保留了Vue 2的大部分钩子,但命名调整:beforeDestroy
→beforeUnmount
destroyed
→unmounted
-
Composition API新增钩子
使用setup()
函数替代beforeCreate
和created
,并通过函数形式访问其他钩子:import { onMounted, onUpdated } from 'vue'; export default { setup() { onMounted(() => { console.log('组件已挂载'); }); onUpdated(() => { console.log('组件已更新'); }); } };
生命周期图示(Vue 3)
创建 → setup() → beforeMount → mounted → 更新 → beforeUpdate → updated → 销毁 → beforeUnmount → unmounted
核心钩子详解与示例
1. created
- 数据已初始化,但DOM未渲染。
- 适用场景:请求接口数据、初始化非DOM相关状态。
export default { data() { return { list: [] }; }, created() { axios.get('/api/data').then(res => this.list = res.data); } };
2. mounted
- DOM已挂载,可操作DOM或集成第三方库。
- 注意:若组件被缓存(如
<keep-alive>
),可能多次触发。mounted() { this.chart = echarts.init(this.$refs.chart); this.renderChart(); }
3. updated
- 数据更新导致DOM更新后触发。
- 慎用:避免在此钩子中修改数据,可能导致无限循环。
updated() { if (this.shouldScroll) { this.$refs.container.scrollTop = this.$refs.container.scrollHeight; } }
4. beforeUnmount
(Vue 3)
- 组件销毁前清理资源。
beforeUnmount() { window.removeEventListener('resize', this.handleResize); clearInterval(this.timer); }
特殊生命周期钩子
-
activated
/deactivated
用于<keep-alive>
缓存的组件,触发激活或停用时的逻辑。activated() { this.startPolling(); // 恢复轮询 }, deactivated() { this.stopPolling(); // 暂停轮询 }
-
errorCaptured
捕获子组件树的错误,可用于错误上报。errorCaptured(err, vm, info) { console.error('捕获到错误:', err, '在组件:', vm, '位置:', info); return false; // 阻止错误继续向上传播 }
生命周期使用注意事项
- 避免在
beforeUpdate
/updated
中修改数据
可能导致递归更新,应通过计算属性或侦听器替代。 - 异步操作与生命周期顺序
异步回调(如setTimeout
)可能跨生命周期阶段执行,需确保操作的有效性。 mounted
不保证子组件已挂载
若需等待子组件渲染完成,使用this.$nextTick()
。mounted() { this.$nextTick(() => { // 所有子组件已挂载 }); }
- Vue 3的
setup()
执行时机
setup()
在beforeCreate
之前运行,此时无法访问this
。
生命周期最佳实践
- 数据初始化:优先在
created
中发起异步请求,减少白屏时间。 - DOM操作:仅在
mounted
后访问DOM,使用ref
替代document.querySelector
。 - 资源清理:在
beforeUnmount
中移除事件监听、定时器等,避免内存泄漏。 - 性能优化:避免在频繁触发的钩子(如
updated
)中执行复杂逻辑。
Vue 2 vs. Vue 3生命周期对比
Vue 2钩子 | Vue 3钩子 | Composition API等效 |
---|---|---|
beforeCreate | - | setup() 替代 |
created | - | setup() 替代 |
beforeMount | beforeMount | onBeforeMount |
mounted | mounted | onMounted |
beforeUpdate | beforeUpdate | onBeforeUpdate |
updated | updated | onUpdated |
beforeDestroy | beforeUnmount | onBeforeUnmount |
destroyed | unmounted | onUnmounted |
总结
- 核心思想:通过生命周期钩子精准控制组件的状态和行为。
- Vue 2到Vue 3:钩子函数命名调整,新增Composition API形式。
- 核心阶段:创建 → 挂载 → 更新 → 销毁,每个阶段对应关键逻辑。
- 最佳实践:合理选择钩子,避免副作用,优化性能与可维护性。
理解Vue生命周期是构建高效、健壮应用的基础,尤其在处理异步操作、资源管理和性能优化时至关重要。