元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
Vue3 基础
▶
环境搭建
安装与配置
项目创建
开发工具
▶
模板语法
插值表达式
指令系统
事件处理
▶
核心概念
▶
响应式系统
ref与reactive
计算属性
侦听器
▶
组合式API
setup函数
生命周期钩子
自定义Hooks
▶
组件开发
▶
组件基础
组件通信
Props详解
插槽机制
▶
高级组件
动态组件
异步组件
递归组件
▶
状态管理
▶
Vuex基础
状态存储
模块化
组合式写法
▶
Pinia
创建Store
状态操作
插件机制
发布时间:
2025-03-22 12:12
↑
☰
# Vue3 生命周期钩子详解 本文将详细介绍Vue3中的生命周期钩子函数,包括它们的执行时机、使用方法和最佳实践。 ## 生命周期概述 ### 1. 组件生命周期 ```javascript // 组件生命周期示意图 Component Creation ↓ Setup (setup) ↓ BeforeCreate (onBeforeMount) ↓ Created (onMounted) ↓ BeforeMount (onBeforeUpdate) ↓ Mounted (onUpdated) ↓ BeforeUpdate (onBeforeUnmount) ↓ Updated (onUnmounted) ↓ BeforeUnmount (onActivated) ↓ Unmounted (onDeactivated) ``` ## 组合式API中的生命周期钩子 ### 1. 基础用法 ```vue <template> <div> <p>{{ message }}</p> </div> </template> <script setup> import { ref, onMounted, onUpdated, onUnmounted } from 'vue' const message = ref('Hello') onMounted(() => { console.log('Component is mounted') }) onUpdated(() => { console.log('Component is updated') }) onUnmounted(() => { console.log('Component is unmounted') }) </script> ``` ### 2. 完整生命周期 ```vue <script setup> import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, onActivated, onDeactivated, onErrorCaptured } from 'vue' // 组件挂载前 onBeforeMount(() => { console.log('Before Mount') }) // 组件挂载后 onMounted(() => { console.log('Mounted') }) // 组件更新前 onBeforeUpdate(() => { console.log('Before Update') }) // 组件更新后 onUpdated(() => { console.log('Updated') }) // 组件卸载前 onBeforeUnmount(() => { console.log('Before Unmount') }) // 组件卸载后 onUnmounted(() => { console.log('Unmounted') }) // keep-alive组件激活时 onActivated(() => { console.log('Component Activated') }) // keep-alive组件停用时 onDeactivated(() => { console.log('Component Deactivated') }) // 错误捕获 onErrorCaptured((err, instance, info) => { console.log('Error Captured:', err, instance, info) return false // 阻止错误继续传播 }) </script> ``` ## 实际应用场景 ### 1. 数据获取 ```vue <template> <div> <div v-if="loading">Loading...</div> <div v-else> <h2>{{ data.title }}</h2> <p>{{ data.content }}</p> </div> </div> </template> <script setup> import { ref, onMounted } from 'vue' const data = ref(null) const loading = ref(true) onMounted(async () => { try { const response = await fetch('https://api.example.com/data') data.value = await response.json() } catch (error) { console.error('Error fetching data:', error) } finally { loading.value = false } }) </script> ``` ### 2. DOM操作 ```vue <template> <div> <canvas ref="chartCanvas"></canvas> </div> </template> <script setup> import { ref, onMounted, onUnmounted } from 'vue' import Chart from 'chart.js' const chartCanvas = ref(null) let chart = null onMounted(() => { // 在DOM可用后初始化图表 chart = new Chart(chartCanvas.value.getContext('2d'), { type: 'bar', data: { labels: ['A', 'B', 'C'], datasets: [{ data: [10, 20, 30] }] } }) }) onUnmounted(() => { // 清理图表资源 if (chart) { chart.destroy() chart = null } }) </script> ``` ### 3. 事件监听 ```vue <script setup> import { onMounted, onUnmounted } from 'vue' const handleScroll = () => { console.log('Window scrolled') } onMounted(() => { // 添加事件监听 window.addEventListener('scroll', handleScroll) }) onUnmounted(() => { // 移除事件监听 window.removeEventListener('scroll', handleScroll) }) </script> ``` ## 最佳实践 ### 1. 资源管理 ```vue <script setup> import { ref, onMounted, onUnmounted } from 'vue' const timer = ref(null) const count = ref(0) onMounted(() => { // 设置定时器 timer.value = setInterval(() => { count.value++ }, 1000) }) onUnmounted(() => { // 清理定时器 if (timer.value) { clearInterval(timer.value) timer.value = null } }) </script> ``` ### 2. 异步操作处理 ```vue <script setup> import { ref, onMounted, onUnmounted } from 'vue' const mounted = ref(false) let controller = null onMounted(async () => { mounted.value = true controller = new AbortController() try { const response = await fetch('https://api.example.com/data', { signal: controller.signal }) // 确保组件仍然挂载 if (mounted.value) { const data = await response.json() // 处理数据 } } catch (error) { if (error.name === 'AbortError') { console.log('Fetch aborted') } else { console.error('Error:', error) } } }) onUnmounted(() => { mounted.value = false if (controller) { controller.abort() controller = null } }) </script> ``` ### 3. 组件通信 ```vue <script setup> import { provide, onMounted, onUnmounted } from 'vue' const eventBus = { listeners: new Map(), on(event, callback) { if (!this.listeners.has(event)) { this.listeners.set(event, new Set()) } this.listeners.get(event).add(callback) }, off(event, callback) { if (this.listeners.has(event)) { this.listeners.get(event).delete(callback) } }, emit(event, data) { if (this.listeners.has(event)) { this.listeners.get(event).forEach(callback => callback(data)) } } } provide('eventBus', eventBus) const handleEvent = (data) => { console.log('Event received:', data) } onMounted(() => { eventBus.on('custom-event', handleEvent) }) onUnmounted(() => { eventBus.off('custom-event', handleEvent) }) </script> ``` ## 注意事项 ### 1. 避免副作用 ```vue <script setup> import { ref, onMounted, onUpdated } from 'vue' const count = ref(0) // 不好的实践 - 可能导致无限循环 onUpdated(() => { count.value++ // 不要在更新钩子中修改响应式数据 }) // 好的实践 onMounted(() => { // 在挂载时进行一次性的初始化 count.value = 1 }) </script> ``` ### 2. 生命周期顺序 ```vue <script setup> import { onBeforeMount, onMounted } from 'vue' // 生命周期钩子会按照定义的顺序执行 onBeforeMount(() => { console.log('Before Mount 1') }) onBeforeMount(() => { console.log('Before Mount 2') }) onMounted(() => { console.log('Mounted 1') }) onMounted(() => { console.log('Mounted 2') }) </script> ``` ## 总结 本文详细介绍了Vue3中的生命周期钩子: 1. 基础概念 - 生命周期流程 - 钩子函数作用 - 执行时机 2. 实际应用 - 数据获取 - DOM操作 - 事件监听 3. 最佳实践 - 资源管理 - 异步操作 - 组件通信 4. 注意事项 - 避免副作用 - 执行顺序 - 清理工作 通过合理使用生命周期钩子,可以更好地控制组件的行为和资源管理。建议在实际开发中根据具体需求选择合适的生命周期钩子,并注意避免常见的陷阱。