Vue3 生命周期钩子详解
概述
Vue3 的生命周期钩子让你可以在组件的不同阶段执行代码。这些钩子就像是组件的"人生阶段",你可以在合适的时机做相应的事情。
生命周期流程图
主要生命周期钩子
1. 创建阶段
onBeforeMount
组件挂载到 DOM 之前调用,此时组件已经完成了响应式数据的设置,但还没有挂载到 DOM。
import { onBeforeMount } from "vue";
export default {
setup() {
onBeforeMount(() => {
console.log("组件即将挂载到DOM");
// 可以在这里做一些准备工作
});
},
};
onMounted
组件挂载到 DOM 后调用,此时可以访问 DOM 元素。
import { onMounted, ref } from "vue";
export default {
setup() {
const titleRef = ref(null);
onMounted(() => {
console.log("组件已挂载到DOM");
console.log("标题元素:", titleRef.value);
// 可以在这里进行DOM操作
if (titleRef.value) {
titleRef.value.style.color = "red";
}
});
return {
titleRef,
};
},
};
2. 更新阶段
onBeforeUpdate
组件更新之前调用,此时数据已经变化,但 DOM 还没有更新。
import { onBeforeUpdate } from "vue";
export default {
setup() {
onBeforeUpdate(() => {
console.log("组件即将更新");
// 可以在这里保存更新前的状态
});
},
};
onUpdated
组件更新后调用,此时 DOM 已经更新完成。
import { onUpdated } from "vue";
export default {
setup() {
onUpdated(() => {
console.log("组件已更新完成");
// 可以在这里进行DOM操作
});
},
};
3. 销毁阶段
onBeforeUnmount
组件卸载之前调用,此时组件实例仍然完全可用。
import { onBeforeUnmount } from "vue";
export default {
setup() {
onBeforeUnmount(() => {
console.log("组件即将卸载");
// 可以在这里清理定时器、事件监听器等
});
},
};
onUnmounted
组件卸载后调用,此时组件实例已经被销毁。
import { onUnmounted } from "vue";
export default {
setup() {
onUnmounted(() => {
console.log("组件已卸载");
// 可以在这里进行最终的清理工作
});
},
};
其他生命周期钩子
onErrorCaptured
捕获后代组件的错误。
import { onErrorCaptured } from "vue";
export default {
setup() {
onErrorCaptured((err, instance, info) => {
console.error("捕获到错误:", err);
console.log("错误来源组件:", instance);
console.log("错误信息:", info);
// 返回 false 阻止错误继续向上传播
return false;
});
},
};
onRenderTracked
当渲染函数追踪依赖时调用(开发模式)。
import { onRenderTracked } from "vue";
export default {
setup() {
onRenderTracked((event) => {
console.log("追踪到依赖:", event);
});
},
};
onRenderTriggered
当依赖变化触发重新渲染时调用(开发模式)。
import { onRenderTriggered } from "vue";
export default {
setup() {
onRenderTriggered((event) => {
console.log("触发重新渲染:", event);
});
},
};
生命周期钩子的使用场景
1. 数据获取
import { onMounted, ref } from "vue";
export default {
setup() {
const users = ref([]);
const loading = ref(false);
const fetchUsers = async () => {
loading.value = true;
try {
const response = await fetch("/api/users");
users.value = await response.json();
} catch (error) {
console.error("获取用户失败:", error);
} finally {
loading.value = false;
}
};
onMounted(fetchUsers);
return {
users,
loading,
};
},
};
2. 事件监听
import { onMounted, onUnmounted } from "vue";
export default {
setup() {
const handleResize = () => {
console.log("窗口大小变化");
};
onMounted(() => {
window.addEventListener("resize", handleResize);
});
onUnmounted(() => {
window.removeEventListener("resize", handleResize);
});
},
};
3. 定时器管理
import { onMounted, onUnmounted, ref } from "vue";
export default {
setup() {
const timer = ref(null);
const count = ref(0);
onMounted(() => {
timer.value = setInterval(() => {
count.value++;
}, 1000);
});
onUnmounted(() => {
if (timer.value) {
clearInterval(timer.value);
}
});
return {
count,
};
},
};
最佳实践
1. 合理使用生命周期钩子
- 只在必要时使用生命周期钩子
- 避免在生命周期钩子中放置过多逻辑
- 将复杂的逻辑提取到独立的函数中
2. 清理资源
- 在
onUnmounted中清理定时器、事件监听器等 - 避免内存泄漏
- 确保资源的正确释放
3. 错误处理
- 使用
onErrorCaptured捕获和处理错误 - 提供用户友好的错误提示
- 记录错误日志用于调试
总结
Vue3 的生命周期钩子为组件提供了完整的生命周期管理能力。通过合理使用这些钩子,你可以在组件的不同阶段执行相应的逻辑,构建出更加健壮和高效的 Vue 应用。
