Vue 3 组合式 API 生命周期钩子学习笔记
学习概述
本文深入解析 Vue 3 中组合式 API 提供的生命周期钩子函数,帮助开发者理解每个钩子的执行时机、使用场景及注意事项。这些钩子在 setup()
函数中同步调用,是构建响应式组件逻辑的核心工具。
钩子函数分类与执行顺序图示
说明:实线为主生命周期流程;虚线为特殊条件或调试用途钩子。
核心生命周期钩子详解
onBeforeMount()
题目重述
注册一个在组件挂载前执行的回调函数。
详解
此钩子在组件完成响应式设置后、首次渲染 DOM 前触发。此时 $el
尚未创建,适合进行初始化操作(如日志记录),但不能访问 DOM 元素。
知识点
组件挂载阶段:指模板编译完成后将虚拟 DOM 渲染为真实 DOM 并插入父容器的过程。
setup() 执行时机:
setup()
在beforeCreate
和created
之间运行,所有组合式钩子必须在此阶段注册。SSR 不兼容性:该钩子在服务端渲染时不执行,确保 DOM 相关代码仅在客户端运行。
onMounted()
题目重述
注册一个在组件挂载完成后执行的回调函数。
详解
组件及其所有同步子组件的 DOM 已插入文档,可安全访问 $refs
和 DOM 节点。常用于启动定时器、绑定事件监听器或发起 API 请求。
<script setup>
import { ref, onMounted } from 'vue'
const el = ref()
onMounted(() => {console.log(el.value) // <div>
})
</script>
<template><div ref="el"></div></template>
知识点
DOM 可访问性:只有当根容器在文档中时,才能保证组件 DOM 也在文档中。
异步组件延迟:若包含
<Suspense>
或异步组件,其内部节点可能尚未挂载。客户端专属:服务器端渲染不会调用此钩子,避免非法 DOM 操作。
onBeforeUpdate()
题目重述
在组件因响应式数据变化而更新前调用。
详解
在此钩子中可读取更新前的 DOM 状态(如文本内容、滚动位置),并安全地修改状态,不会导致重复渲染。
知识点
响应式依赖追踪:Vue 使用依赖收集机制,在 getter 中追踪,在 setter 中触发更新。
批量更新策略:多个状态变更会合并到一次渲染周期中以提升性能。
避免无限循环:不应在此钩子中更改会导致当前组件重新渲染的状态。
onUpdated()
题目重述
在组件 DOM 更新后调用。
详解
父组件的 onUpdated
在其子组件更新后才执行。适用于验证 DOM 是否正确更新。禁止在此钩子中修改状态,否则可能引发无限更新循环。
<script setup>
import { ref, onUpdated } from 'vue'
const count = ref(0)
onUpdated(() => {console.log(document.getElementById('count').textContent) // 应等于 count.value
})
</script>
<template><button id="count" @click="count++">{{ count }}</button></template>
知识点
DOM 同步更新:虚拟 DOM 差异对比完成后立即更新真实 DOM。
nextTick 替代方案:若需等待特定状态后的 DOM 更新,应使用
$nextTick()
。性能优化意识:频繁触发可能导致性能问题,建议节流处理。
onBeforeUnmount()
题目重述
在组件卸载前执行的钩子。
详解
组件仍具备完整功能,可用于清理资源(如取消订阅、清除定时器)。常见于手动管理副作用的场景。
知识点
副作用清理原则:任何在
setup
或生命周期中注册的外部资源都应在卸载前释放。内存泄漏防范:未清理的定时器或事件监听器会导致组件实例无法被垃圾回收。
父子卸载顺序:父组件的
beforeUnmount
在子组件之后调用。
onUnmounted()
题目重述
在组件完全卸载后调用。
详解
所有子组件已卸载,响应式系统已停止。典型用途包括清除 setInterval
、解绑全局事件、关闭 WebSocket 连接等。
<script setup>
import { onMounted, onUnmounted } from 'vue'
let intervalId
onMounted(() => {intervalId = setInterval(() => { /* ... */ }, 1000)
})
onUnmounted(() => clearInterval(intervalId))
</script>
知识点
资源释放时机:确保在组件销毁后不再执行任何回调。
异步任务中断:正在进行的请求应主动取消(如 AbortController)。
作用域隔离:避免闭包引用导致的内存驻留。
onActivated() 与 onDeactivated()
题目重述
分别在 <KeepAlive>
缓存组件激活和失活时调用。
详解
用于控制被缓存组件的行为。例如暂停轮播图、恢复动画、重新连接实时数据流等。
<script setup>
import { onActivated, onDeactivated } from 'vue'
onActivated(() => {console.log('组件被激活')
})
onDeactivated(() => {console.log('组件被缓存')
})
</script>
知识点
KeepAlive 缓存机制:通过
include/exclude
控制哪些组件可被缓存,提升切换性能。状态保留特性:组件状态在失活时不丢失,重新激活时恢复原貌。
资源按需启停:避免后台组件持续消耗资源。
onErrorCaptured()
题目重述
捕获后代组件错误时执行的钩子。
详解
接收三个参数:err
, instance
, info
。可用于展示错误界面,并通过返回 false
阻止错误继续冒泡。
<script setup>
import { onErrorCaptured } from 'vue'
onErrorCaptured((err, instance, info) => {console.error('Error captured:', err, info)return false // 阻止向上传递
})
</script>
知识点
错误冒泡机制:类似于 DOM 事件,从子组件向祖先逐层传递。
统一错误处理:可通过
app.config.errorHandler
收集所有未被捕获的错误。防止无限循环:错误处理逻辑本身不应抛出新错误。
onRenderTracked() 与 onRenderTriggered()
题目重述
开发环境下调试响应式依赖的钩子。
详解
onRenderTracked
:追踪依赖时触发(如读取响应式属性)。onRenderTriggered
:依赖变更触发渲染时调用(如赋值操作)。
onRenderTracked((event) => {console.log('[tracked]', event.key)
})onRenderTriggered((event) => {console.log('[triggered]', event.key, 'from', event.oldValue, 'to', event.newValue)
})
知识点
响应式原理可视化:帮助理解 Vue 如何侦听和触发更新。
性能调优辅助:识别不必要的依赖追踪或过度渲染。
仅限开发模式:生产环境不生效,不影响性能。
onServerPrefetch()
题目重述
在服务端渲染前预取数据的异步钩子。
详解
返回 Promise,SSR 会等待其 resolve 再渲染组件。用于服务端数据预加载,提高首屏性能。
<script setup>
import { ref, onServerPrefetch } from 'vue'
const data = ref(null)
onServerPrefetch(async () => {data.value = await fetchOnServer()
})
</script>
知识点
同构数据获取:实现“一次编写,两端运行”的数据加载逻辑。
客户端降级策略:若服务端无数据,则客户端再请求。
SEO 优化手段:确保初始 HTML 包含完整内容。
总结表格:生命周期钩子对比
钩子名 | 触发时机 | SSR 是否可用 | 典型用途 |
---|---|---|---|
onBeforeMount | 挂载前 | ❌ | 初始化非 DOM 操作 |
onMounted | 挂载后 | ❌ | 访问 DOM、启动定时器 |
onBeforeUpdate | 更新前 | ❌ | 记录更新前状态 |
onUpdated | 更新后 | ❌ | 验证 DOM 更新结果 |
onBeforeUnmount | 卸载前 | ❌ | 清理副作用 |
onUnmounted | 卸载后 | ❌ | 移除事件/定时器 |
onActivated | KeepAlive 激活 | ❌ | 恢复动画、连接数据流 |
onDeactivated | KeepAlive 失活 | ❌ | 暂停资源消耗 |
onErrorCaptured | 捕获后代错误 | ✅ | 错误边界处理 |
onRenderTracked | 追踪依赖时(开发) | ❌ | 调试响应式依赖 |
onRenderTriggered | 依赖触发更新时(开发) | ❌ | 分析渲染原因 |
onServerPrefetch | 服务端渲染前预取数据 | ✅(仅服务端) | 服务端数据预加载 |
关键知识点汇总
setup() 同步调用规则:所有生命周期钩子必须在
setup()
或<script setup>
中同步注册,否则无法正确绑定。客户端与服务端差异:除
onErrorCaptured
和onServerPrefetch
外,其余钩子在 SSR 期间均不执行。副作用清理机制:组件卸载时务必清除所有外部资源引用,防止内存泄漏和意外行为。
💡 学习建议:结合 Chrome DevTools 的 Vue 插件观察组件生命周期流动,配合
console.log
调试各钩子执行顺序,加深理解。