生命周期钩子
组合式 API 中的生命周期钩子
在 Vue3 的组合式 API 中,生命周期钩子函数被设计为可导入的函数,而不是选项式 API 中的方法。这些钩子函数需要在 setup() 函数中调用。
1. 生命周期钩子列表
Vue3 提供了以下生命周期钩子函数:
| 组合式 API | 选项式 API | 描述 |
|---|---|---|
| onBeforeMount | beforeMount | 组件挂载前调用 |
| onMounted | mounted | 组件挂载后调用 |
| onBeforeUpdate | beforeUpdate | 组件更新前调用 |
| onUpdated | updated | 组件更新后调用 |
| onBeforeUnmount | beforeUnmount | 组件卸载前调用 |
| onUnmounted | unmounted | 组件卸载后调用 |
| onErrorCaptured | errorCaptured | 捕获子组件错误时调用 |
| onRenderTracked | - | 组件渲染时追踪依赖 |
| onRenderTriggered | - | 组件重新渲染时触发 |
| onActivated | - | KeepAlive 组件激活时调用 |
| onDeactivated | - | KeepAlive 组件停用时调用 |
2. 基本使用
在 setup() 函数中导入并使用生命周期钩子。
示例:使用生命周期钩子
<script setup>
import {
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted
} from 'vue';
// 组件挂载前
onBeforeMount(() => {
console.log('组件挂载前');
});
// 组件挂载后
onMounted(() => {
console.log('组件挂载后');
// 可以在这里进行 DOM 操作
const element = document.getElementById('my-element');
if (element) {
element.textContent = 'Hello from mounted';
}
});
// 组件更新前
onBeforeUpdate(() => {
console.log('组件更新前');
});
// 组件更新后
onUpdated(() => {
console.log('组件更新后');
// 可以在这里获取更新后的 DOM
});
// 组件卸载前
onBeforeUnmount(() => {
console.log('组件卸载前');
// 清理资源,如事件监听器、定时器等
clearInterval(timer);
});
// 组件卸载后
onUnmounted(() => {
console.log('组件卸载后');
});
// 定时器示例
let timer;
onMounted(() => {
timer = setInterval(() => {
console.log('定时器执行');
}, 1000);
});
onBeforeUnmount(() => {
clearInterval(timer);
});
</script>
3. 错误捕获
使用 onErrorCaptured() 钩子可以捕获子组件的错误。
示例:捕获错误
<script setup>
import { onErrorCaptured } from 'vue';
onErrorCaptured((err, vm, info) => {
console.log('捕获到错误:', err);
console.log('错误组件:', vm);
console.log('错误信息:', info);
// 返回 true 可以阻止错误继续向上传播
return false;
});
</script>
4. 渲染追踪
Vue3 提供了两个用于调试的生命周期钩子:
示例:渲染追踪
<script setup>
import { onRenderTracked, onRenderTriggered } from 'vue';
// 组件渲染时追踪依赖
onRenderTracked((event) => {
console.log('渲染追踪:', event);
// event 包含:
// - key: 追踪的属性名
// - target: 追踪的目标对象
// - type: 追踪类型(getter, setter, ...)
});
// 组件重新渲染时触发
onRenderTriggered((event) => {
console.log('渲染触发:', event);
// event 包含:
// - key: 触发更新的属性名
// - target: 触发更新的目标对象
// - type: 触发类型(setter, ...)
// - newValue: 新值
// - oldValue: 旧值
});
</script>
5. KeepAlive 相关钩子
当组件被 KeepAlive 包裹时,会触发 onActivated 和 onDeactivated 钩子。
示例:KeepAlive 钩子
<script setup>
import { onActivated, onDeactivated } from 'vue';
onActivated(() => {
console.log('组件激活');
// 可以在这里恢复状态
});
onDeactivated(() => {
console.log('组件停用');
// 可以在这里保存状态
});
</script>
6. 生命周期钩子的执行顺序
生命周期钩子的执行顺序如下:
- onBeforeMount
- onMounted
- onBeforeUpdate
- onUpdated
- onBeforeUnmount
- onUnmounted
7. 与选项式 API 混合使用
在 Vue3 中,可以混合使用组合式 API 和选项式 API 的生命周期钩子。
示例:混合使用生命周期钩子
<script>
import { onMounted } from 'vue';
export default {
// 选项式 API 生命周期
mounted() {
console.log('选项式 API: mounted');
},
// 组合式 API 生命周期
setup() {
onMounted(() => {
console.log('组合式 API: onMounted');
});
}
}
// 执行顺序:
// 组合式 API: onMounted
// 选项式 API: mounted
</script>
8. 生命周期钩子的最佳实践
- 在 onMounted 中进行 DOM 操作和数据请求
- 在 onBeforeUnmount 中清理资源,如事件监听器、定时器、WebSocket 连接等
- 使用 onErrorCaptured 捕获和处理子组件的错误
- 避免在生命周期钩子中进行过于复杂的计算
- 合理使用 KeepAlive 相关钩子管理组件状态
9. 生命周期钩子的注意事项
- 生命周期钩子必须在 setup() 函数中调用
- 每个生命周期钩子可以多次调用,它们会按照注册顺序执行
- onMounted 等钩子在服务器端渲染时不会执行
- onErrorCaptured 只能捕获子组件的错误,不能捕获自身的错误