生命周期钩子
什么是生命周期?
生命周期: 指的是一个 Vue 组件从 创建 → 挂载 → 更新 → 销毁 的完整过程。
类比人的一生:
- 出生(组件创建) → 上学(挂载到页面) → 工作变化(数据更新) → 退休(组件销毁)。
每个阶段都有特定的任务需要处理(如初始化数据、操作 DOM、清理资源等),这就是生命周期的意义。
什么是钩子函数?
钩子函数(Lifecycle Hooks) 是 Vue 在生命周期不同阶段自动调用的函数。
开发者可以在这些函数中编写代码,干预组件的各个阶段,就像在关键时间点插入“钩子”执行逻辑。
例如:
- 组件初始化完成时(
created
),可以发起网络请求。 - 组件挂载到页面后(
mounted
),可以操作 DOM。 - 组件销毁前(
beforeUnmount
),可以清理定时器。
Vue 3 生命周期流程图
以下是 Vue 3 的生命周期流程图,展示了钩子函数的执行顺序:
初始化阶段↓
setup() → Composition API 入口(替代 Vue 2 的 beforeCreate 和 created)↓
beforeMount → 组件挂载到 DOM 前↓
mounted → 组件已挂载到 DOM↓
更新阶段(数据变化时触发)↓
beforeUpdate → 数据更新,DOM 重新渲染前↓
updated → DOM 更新完成↓
卸载阶段↓
beforeUnmount → 组件销毁前↓
unmounted → 组件已销毁
Vue 3 钩子函数详解(Composition API 写法)
在 Vue 3 的 Composition API 中,钩子函数以 onX
形式导入使用:
钩子函数 | 作用 | 使用场景 |
---|---|---|
onBeforeMount | 组件挂载到 DOM 前触发 | 极少使用 |
onMounted | 组件挂载到 DOM 后触发 | 操作 DOM、初始化第三方库(如图表) |
onBeforeUpdate | 数据变化导致 DOM 更新 前触发 | 获取更新前的 DOM 状态 |
onUpdated | DOM 更新 后触发 | 依赖 DOM 的后续操作(谨慎使用,避免循环) |
onBeforeUnmount | 组件销毁 前触发 | 清理定时器、取消事件监听 |
onUnmounted | 组件销毁 后触发 | 释放内存资源 |
示例代码:
import { onMounted, onUnmounted } from 'vue';export default {setup() {// 组件挂载后执行onMounted(() => {console.log('组件已挂载');// 例如:初始化图表});// 组件销毁前执行onUnmounted(() => {console.log('组件即将销毁');// 例如:清除定时器});}
};
为什么需要生命周期钩子?
- 控制代码执行时机
确保在正确的时间做正确的事(如 DOM 未渲染时无法操作元素)。 - 资源管理
避免内存泄漏(如及时清理定时器、事件监听)。 - 逻辑解耦
将不同阶段的代码分离,提高可维护性。
Vue2与Vue3生命周期对比
以下是 Vue 2 和 Vue 3 生命周期函数的对比详解,包含核心差异、用法和迁移指南:
阶段 | Vue 2 生命周期钩子 | Vue 3 生命周期钩子 | Vue 3 Composition API 钩子 |
---|---|---|---|
初始化阶段 | beforeCreate | ❌ 无(被 setup 替代) | 无(setup 替代) |
created | ❌ 无(被 setup 替代) | 无(setup 替代) | |
挂载阶段 | beforeMount | beforeMount | onBeforeMount |
mounted | mounted | onMounted | |
更新阶段 | beforeUpdate | beforeUpdate | onBeforeUpdate |
updated | updated | onUpdated | |
卸载阶段 | beforeDestroy | beforeUnmount (重命名) | onBeforeUnmount |
destroyed | unmounted (重命名) | onUnmounted | |
缓存组件 | activated | activated | onActivated |
deactivated | deactivated | onDeactivated | |
开发调试 | ❌ 无 | ❌ 无 | onRenderTracked (新增) |
❌ 无 | ❌ 无 | onRenderTriggered (新增) |
核心差异详解
1. beforeCreate
和 created
的替代
-
Vue 2:在实例初始化前后触发,常用于初始化数据或异步请求。
-
Vue 3:被
setup()
函数替代,所有初始化逻辑应在setup
中完成。// Vue 3 的 setup 替代 created setup() {const data = fetchData(); // 直接执行初始化逻辑return { data }; }
2. 卸载阶段钩子重命名
-
Vue 2:
beforeDestroy
和destroyed
。 -
Vue 3:更语义化的命名:
// Options API beforeUnmount() { /* ... */ }, unmounted() { /* ... */ }// Composition API import { onBeforeUnmount, onUnmounted } from 'vue'; setup() {onBeforeUnmount(() => { /* 清理定时器等 */ });onUnmounted(() => { /* 移除事件监听 */ }); }
3. 新增调试钩子
-
onRenderTracked
:追踪虚拟 DOM 渲染依赖(开发模式)。 -
onRenderTriggered
:追踪虚拟 DOM 重新渲染触发原因(开发模式)。import { onRenderTracked, onRenderTriggered } from 'vue'; setup() {onRenderTracked((e) => {console.log('依赖追踪:', e);});onRenderTriggered((e) => {console.log('重新渲染触发:', e);}); }
Vue 3 生命周期使用示例
1. Options API 写法(兼容 Vue 2 风格)
export default {beforeMount() {console.log('DOM 挂载前');},mounted() {console.log('DOM 挂载完成');},beforeUnmount() {console.log('组件卸载前');},unmounted() {console.log('组件已卸载');}
};
2. Composition API 写法(推荐)
import { onMounted, onUnmounted } from 'vue';export default {setup() {onMounted(() => {console.log('DOM 挂载完成');// 初始化操作(如请求数据、添加事件监听)});onUnmounted(() => {console.log('组件已卸载');// 清理操作(如移除事件监听、取消定时器)});return {};}
};
迁移指南(Vue 2 → Vue 3)
1. 直接重命名的情况
Vue 2 钩子 | Vue 3 钩子 |
---|---|
beforeDestroy | beforeUnmount |
destroyed | unmounted |
2. 需要替换的情况
beforeCreate
和created
:将逻辑移至setup()
。this
访问:在setup()
中无法访问this
,需通过参数或 Composition API 获取上下文。
3. 异步请求的位置
-
Vue 2:通常在
created
或mounted
中发起请求。 -
Vue 3:推荐在
onMounted
中执行:setup() {const data = ref(null);onMounted(async () => {data.value = await fetchData();});return { data }; }
常见问题
1. Vue 3 中能否同时使用 Options API 和 Composition API?
- 可以,但推荐统一风格。例如,在
setup
中使用 Composition API 钩子,避免混用。
2. 为什么 Vue 3 移除了 beforeCreate
和 created
?
- 这两个阶段的逻辑被
setup
函数完全替代,setup
的执行时机在beforeCreate
之前。
3. 如何监听 props 变化?
-
使用
watch
或watchEffect
:setup(props) {watch(() => props.id, (newId) => {fetchData(newId);}); }
4. created
和 mounted
有什么区别?
created
(Vue 2):组件数据已初始化,但 DOM 未生成。mounted
:DOM 已渲染完成,可安全操作元素。
在 Vue 3 中,setup
替代了created
,初始化逻辑应写在setup
或onMounted
中。
5. 异步请求放在哪个钩子?
- 推荐在
onMounted
中(确保 DOM 已挂载,适合依赖 DOM 的操作)。 - 如果无需 DOM,也可在
setup
中直接调用。
6. 为什么 onUpdated
要慎用?
- 在
onUpdated
中修改数据可能导致无限循环(数据变化 → 触发更新 → 再次修改数据)。