vue 3组合式api中,生命周期钩子如onmounted必须在setup函数顶层同步调用,不可置于异步回调、定时器或条件语句中;需从vue导入,用于组件挂载、更新、卸载等阶段的逻辑处理。

在 Vue 3 的组合式 API 中,setup 是组件的入口函数,而生命周期钩子(如 onMounted、onUnmounted 等)不再作为选项写在对象里,而是以函数形式在 setup 内部调用。
✅ 在 setup 中正确使用 onMounted 等钩子
这些钩子必须在 setup() 同步执行期间调用(不能放在异步回调、定时器或条件语句中),否则会失效或报错。Vue 依赖调用顺序来建立响应式关联。
- 直接在 setup 函数体顶层调用:这是最常见也最安全的方式
- 不能在 async setup 中直接 await 后调用:因为 setup 返回 Promise 时,生命周期钩子需在返回前注册
- 可在 setup 内定义的事件处理函数、计算属性、watch 中使用,但钩子本身必须提前注册
? 常见生命周期钩子对照与用法
组合式 API 中的钩子名称与选项式 API 类似,只是加了 on 前缀,且全部从 vue 导入:
-
onBeforeMount→ 模板编译完成、挂载前 -
onMounted→ 组件已挂载到 DOM,可安全操作 DOM 元素 -
onBeforeUpdate→ 响应式数据变更、更新前 -
onUpdated→ 模板更新并重新渲染后 -
onBeforeUnmount→ 组件卸载前(如路由离开、v-if 变 false) -
onUnmounted→ 组件已从 DOM 移除,清理定时器、事件监听等放这里
? 实际代码示例
以下是一个典型用法:
import { defineComponent, onMounted, onUnmounted, ref } from 'vue'
export default defineComponent({
setup() {
const count = ref(0)
// ✅ 正确:在 setup 顶层同步注册
onMounted(() => {
console.log('组件已挂载')
// 可访问 DOM,例如:document.getElementById('my-el')
})
onUnmounted(() => {
console.log('组件已卸载')
// 清理资源
})
return {
count
}
}
})
⚠️ 容易踩的坑
-
在 setup 中使用
async时,不能直接 await 后再调用 onMounted:这会导致钩子未被注册 -
不要在
watch或computed内部调用生命周期钩子:它们不是响应式副作用,也不属于运行时逻辑 - SSR 场景下,onMounted / onBeforeMount 等仅在客户端执行:服务端渲染时不触发,需注意逻辑隔离










