Vue2 和 Vue3 生命周期的理解与对比
我对 Vue2 和 Vue3 生命周期的理解与对比
在日常的前端开发中,我经常会接触到组件的生命周期问题。无论是在数据请求、DOM 操作还是资源清理的场景中,生命周期都起着非常重要的作用。
我在学习 Vue 的过程中,发现 Vue2 和 Vue3 的生命周期函数 虽然本质相同,但在设计和使用方式上发生了很大的变化。
这篇文章,我想结合自己的理解,系统地总结一下 Vue2 和 Vue3 的生命周期差异与使用心得。
一、我理解的生命周期
生命周期(Lifecycle)指的是一个 Vue 组件从被创建、挂载、更新到销毁的整个过程。
Vue 为每一个阶段都提供了钩子函数(Hook),让我可以在不同的时机执行相应的逻辑,比如:
- 在组件创建时获取数据;
 - 在挂载后操作真实的 DOM;
 - 在更新前后执行副作用;
 - 在销毁前清理定时器或事件监听器。
 
简单来说:
生命周期就是 Vue 帮我在“组件从生到死”的过程中,提供了多个可编程的时机点。
二、Vue2 的生命周期
在 Vue2 中,我通常使用选项式 API(Options API)来定义生命周期函数。
它的生命周期函数大致可以分为四个阶段:创建、挂载、更新和销毁。
| 阶段 | 钩子函数 | 说明 | 
|---|---|---|
| 创建阶段 | beforeCreate | 实例初始化之前调用,此时 data、methods 都还未定义 | 
| 创建阶段 | created | 实例创建完成,可以访问 data 和 methods,但 DOM 还未挂载 | 
| 挂载阶段 | beforeMount | 模板编译完成,准备挂载到 DOM 前调用 | 
| 挂载阶段 | mounted | 组件挂载完成,DOM 可操作 | 
| 更新阶段 | beforeUpdate | 数据更新前调用,此时 DOM 还未更新 | 
| 更新阶段 | updated | 数据更新并重新渲染后调用 | 
| 销毁阶段 | beforeDestroy | 实例销毁前调用,常用于解绑事件、清理定时器 | 
| 销毁阶段 | destroyed | 实例销毁后调用,组件完全被移除 | 
我理解的生命周期流程图:
beforeCreate → created → beforeMount → mounted → beforeUpdate → updated → beforeDestroy → destroyed
示例代码:
export default {data() {return { count: 0 }},beforeCreate() {console.log('beforeCreate:组件实例刚被创建')},created() {console.log('created:实例已创建,可访问 data')},mounted() {console.log('mounted:DOM 已挂载')},beforeUpdate() {console.log('beforeUpdate:数据更新前')},updated() {console.log('updated:DOM 已更新')},beforeDestroy() {console.log('beforeDestroy:组件即将销毁')},destroyed() {console.log('destroyed:组件已销毁')}
}
在 Vue2 中,生命周期函数通过对象属性定义,逻辑会分散在不同的选项里。当项目变得复杂时,逻辑复用和管理会变得困难。
三、Vue3 的生命周期
当我开始学习 Vue3 时,最直观的变化就是引入了 Composition API(组合式 API)。
生命周期的定义方式也随之改变,从“对象式定义”转变为“函数式调用”。
| 阶段 | Vue2 写法 | Vue3 写法 | 说明 | 
|---|---|---|---|
| 创建前 | beforeCreate | ❌ 移除,逻辑在 setup() 中实现 | |
| 创建后 | created | ❌ 移除,逻辑在 setup() 中实现 | |
| 挂载前 | beforeMount | onBeforeMount | 组件挂载前调用 | 
| 挂载后 | mounted | onMounted | 组件挂载后调用 | 
| 更新前 | beforeUpdate | onBeforeUpdate | 组件更新前调用 | 
| 更新后 | updated | onUpdated | 组件更新后调用 | 
| 销毁前 | beforeDestroy | onBeforeUnmount | 组件卸载前调用 | 
| 销毁后 | destroyed | onUnmounted | 组件卸载后调用 | 
示例代码:
<script setup>
import { ref, onMounted, onUpdated, onUnmounted } from 'vue'const count = ref(0)onMounted(() => {console.log('onMounted:组件已挂载')
})onUpdated(() => {console.log('onUpdated:组件已更新')
})onUnmounted(() => {console.log('onUnmounted:组件已卸载')
})
</script><template><div><p>{ count }</p><button @click="count++">点击增加</button></div>
</template>
在 Vue3 中,beforeCreate 和 created 已经被合并到 setup() 阶段。
我可以在 setup() 内直接访问 props、定义响应式变量、监听生命周期。
四、Vue2 与 Vue3 生命周期对比总结
| 生命周期阶段 | Vue2 | Vue3(组合式 API) | 
|---|---|---|
| 创建前 | beforeCreate | ❌(已移除) | 
| 创建后 | created | ❌(已移除) | 
| 挂载前 | beforeMount | onBeforeMount | 
| 挂载后 | mounted | onMounted | 
| 更新前 | beforeUpdate | onBeforeUpdate | 
| 更新后 | updated | onUpdated | 
| 销毁前 | beforeDestroy | onBeforeUnmount | 
| 销毁后 | destroyed | onUnmounted | 
| 错误捕获 | errorCaptured | onErrorCaptured | 
| keep-alive 激活 | activated | onActivated | 
| keep-alive 失活 | deactivated | onDeactivated | 
五、我对 Vue3 生命周期的看法
我认为 Vue3 在生命周期的设计上更符合逻辑复用的需求。
几个我非常喜欢的改进包括:
- 
逻辑更加集中:
所有的生命周期都可以在setup()中统一管理,逻辑清晰。 - 
类型提示更友好:
在使用 TypeScript 时,onMounted()、onUpdated()等函数能获得完整类型支持。 - 
组合逻辑更强大:
我可以把生命周期逻辑封装进自定义 Hook 中,比如useFetch、useMouse等,更方便复用。 - 
更贴近函数式编程思想:
生命周期的调用方式像 React Hooks,函数式开发体验更好。 
六、我的总结
| 对比项 | Vue2 | Vue3 | 
|---|---|---|
| 核心写法 | 选项式 API | 组合式 API | 
| 生命周期入口 | beforeCreate、created | setup() | 
| 生命周期命名 | 英文过去式(mounted) | on + 生命周期名(onMounted) | 
| 灵活性 | 逻辑分散,复用较难 | 逻辑集中,易于复用 | 
| 类型支持 | 弱 | 强(天然支持 TypeScript) | 
七、结语
通过学习和使用 Vue3 的生命周期,我感受到它的设计更加现代化。
它不再是简单的钩子函数堆叠,而是一种可组合、可复用的逻辑组织方式。
如果说 Vue2 是一种“配置式开发”,那么 Vue3 更像是一种“逻辑式开发”。
我认为这也是前端框架演进的趋势:让开发者能更清晰地表达逻辑关系,而不是被固定的结构限制。
✨ 总结一句话:
Vue3 的生命周期让我的代码更简洁、更模块化,也更有乐趣。
作者:韩佳俊
时间:2025-11-03
前端开发工程师 · 持续学习中 🚀
