created和beforecreate总是触发;mounted、beforemount等依赖dom的钩子仅在mount后触发;unmounted需显式调用unmount()才执行;测试mounted须用mount并attachto文档,更新需nexttick,销毁需手动unmount。

Vue 组件测试中,生命周期钩子的触发行为取决于测试环境和挂载方式,不是自动全量执行的。真实触发与否,关键看组件是否真正经历了“创建→挂载→更新→卸载”这一完整流程,而单元测试默认不会走 DOM 挂载环节。
测试中哪些钩子会触发?
在使用 @vue/test-utils(v2 或 v4)进行组件测试时:
- created 和 beforeCreate 总是触发 —— 它们属于实例初始化阶段,只要 new Vue() 或 setup() 执行就会运行,与是否挂载无关;
- mounted、beforeMount、updated、beforeUpdate 等依赖 DOM 或渲染的钩子,**仅当组件被实际挂载(mount)后才会触发**;
-
unmounted 和 beforeUnmount 只有在测试中显式调用
wrapper.unmount()后才执行; - 服务端渲染(SSR)上下文或 Jest 的纯 JS 环境中,mounted 类钩子默认不触发 —— 因为没有真实 DOM。
如何确保 mounted 钩子被测试到?
必须使用 mount() 而非 shallowMount()(v2)或 render()(v4 组合式 API 测试常用),并确认容器已附加到 document:
- v2 写法:
const wrapper = mount(MyComponent); - v4(@vue/test-utils@next)推荐:
const wrapper = mount(MyComponent, { attachTo: document.body }); - 若用
render()(基于 @testing-library/vue),需搭配await waitFor(() => expect(...))等待 DOM 就绪,mounted 才会执行; - 测试后记得清理:
document.body.innerHTML = ''或使用afterEach(() => wrapper.unmount())。
更新和销毁阶段的测试要点
验证 beforeUpdate 和 updated,需主动触发响应式变更并等待更新完成:
- 修改响应式数据后,用
await wrapper.vm.$nextTick()(选项式)或await nextTick()(组合式)确保 DOM 更新完毕; - 测试 beforeUnmount 和 unmounted,要显式调用
wrapper.unmount(),并在钩子内做标记(如console.log或写入全局变量),再断言该标记是否出现; - 注意:在 updated 中修改状态会引发警告甚至死循环,测试时也应避免此类写法。
常见陷阱与绕过方式
有些场景下钩子看似没触发,其实只是条件未满足:
- 用了
shallowMount→ 子组件被 stub,但父组件自身的 mounted 仍会触发(只要它被挂载); - 组件含
<suspense></suspense>或异步组件 → mounted 触发时机延迟,需 awaitflushPromises()或使用await waitFor; - 想跳过 DOM 操作只测逻辑?可直接在
setup()中提取逻辑函数,单独单元测试,无需依赖生命周期钩子; - 对 onMounted 等组合式 API 钩子,可用 jest.mock('vue') 模拟其行为,验证回调是否被注册,而不必真实挂载。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











