先记住这个答案
常用对应关系是 beforeMount/onBeforeMount、mounted/onMounted、beforeUpdate/onBeforeUpdate、updated/onUpdated、beforeUnmount/onBeforeUnmount、unmounted/onUnmounted;errorCaptured、renderTracked、renderTriggered、activated、deactivated 和 serverPrefetch 也分别有 onErrorCaptured、onRenderTracked、onRenderTriggered、onActivated、onDeactivated、onServerPrefetch。组合式 API 没有 onBeforeCreate 和 onCreated,相关初始化直接写在 setup 中。钩子应在 setup 同步注册,并注意服务端只运行适用的服务端流程。
- 大部分运行阶段存在 on 前缀对应钩子
- beforeCreate 与 created 逻辑直接进入 setup
- 钩子必须在组件同步初始化时登记
常用对应可以按阶段成对记忆
挂载、更新和卸载都有 before 与完成后的两端。onMounted 表示组件自己的节点已创建,onUpdated 表示一次更新完成,onUnmounted 则适合确认组件拥有的资源已经结束;具体顺序还要结合父子组件分析。
onActivated 与 onDeactivated 服务 KeepAlive 缓存切换,不能用 mounted 与 unmounted 完整替代。错误捕获和渲染调试钩子也有对应组合式函数,但它们不是常规业务状态流的替代品。
没有 created 钩子函数并非少了阶段
setup 本身就在选项式 beforeCreate 与 created 所覆盖的初始化阶段运行,因此 ref、computed、watch 和普通初始化可以直接写在 setup。需要 DOM 的代码仍必须等待挂载,不能因为它来自原 created 就假定节点已经存在。
迁移时按一项功能把状态、计算、监听和清理放在同一个 composable,比把所有 mounted 逻辑集中复制到一个巨大回调更容易追踪。下面的骨架展示对应名称和清理位置。
import {
h, onBeforeMount, onMounted, onBeforeUpdate,
onUpdated, onBeforeUnmount, onUnmounted
} from 'vue'
const lifecycleEvents: string[] = []
const LifecycleProbe = {
setup() {
lifecycleEvents.push('setup')
onBeforeMount(() => lifecycleEvents.push('beforeMount'))
onMounted(() => lifecycleEvents.push('mounted'))
onBeforeUpdate(() => lifecycleEvents.push('beforeUpdate'))
onUpdated(() => lifecycleEvents.push('updated'))
onBeforeUnmount(() => lifecycleEvents.push('beforeUnmount'))
onUnmounted(() => lifecycleEvents.push('unmounted'))
return () => h('span', 'ready')
}
}这些调用现在都位于组件 setup 的同步初始化中。lifecycleEvents 仅用于受控测试观察,实际逻辑应围绕资源与功能组织;模块顶层直接调用不会自动获得组件实例。
SSR 与客户端钩子要分别判断
服务端渲染不会拥有浏览器 DOM,mounted 和 updated 这类客户端钩子不会在服务端输出阶段替你执行节点操作。需要服务端等待数据时使用框架与 onServerPrefetch 等明确机制,并将结果正确传给客户端。
同一组件随后在浏览器挂载或水合时,客户端生命周期仍要面对环境差异。不要在 setup 无条件读取 window,也不要把 onMounted 的客户端补数据当成已经进入初始服务端 HTML 的内容。
容易答错的地方
- 寻找 onCreated 并用 onMounted 代替
- created 阶段逻辑不要求 DOM,直接放入 setup 即可。全部挪到 onMounted 会无意义地延后数据和监听初始化,也可能让首屏渲染缺少本可同步得到的状态。
- 把钩子放进点击或异步回调中注册
- 生命周期 API 依赖当前组件实例上下文。事件触发或普通 await 继续执行时注册通常已经错过同步 setup,应在初始化阶段登记,让回调内部再读取当时状态。
面试官还会怎么问?
beforeDestroy 和 destroyed 在 Vue 3 对应什么?
Vue 3 选项式名称改为 beforeUnmount 与 unmounted,组合式对应 onBeforeUnmount 与 onUnmounted。迁移时也要检查旧插件是否仍依赖 Vue 2 名称。
onMounted 能访问所有异步子组件吗?
它保证同步子组件已挂载,不保证异步组件或 Suspense 分支已经完成。需要异步后代时,应使用它自身的完成信号,不能从父级 mounted 推导全部内容已就绪。
为什么 setup 里不能直接访问 this?
组合式 API 通过闭包中的 props、refs、computed 和返回值组织逻辑,不建立 Options 方法所依赖的组件 this。迁移时应显式引用数据,而不是尝试复制 this 调用。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。