第 20 题:Vue3 生命周期 + watch 执行顺序
🎯 一、核心问题
问:Vue3 中生命周期函数的执行顺序是怎样的?watch / onMounted / onBeforeUnmount 如何配合使用?
-
面试官重点考察:
- 生命周期顺序
- watch 执行时机
- 响应式更新与生命周期的关系
🎯 二、Vue3 生命周期顺序(组合式 API)
-
setup() 执行
- 初始化 props、state、ref、computed、watch
- 可以在 setup 中注册生命周期函数
-
onBeforeMount
- 组件挂载前触发
- 还未渲染到 DOM
-
onMounted
- 组件挂载完成,DOM 已渲染
- 可以操作真实 DOM
-
响应式数据变化触发 watch
- 如果 watch 在 setup 中注册
- flush 默认是
'pre',在 DOM 更新前执行 - flush:
'post'→ 在 DOM 更新后执行
-
onBeforeUnmount
- 组件卸载前触发
- 可清理定时器、事件监听等
-
onUnmounted
- 组件已卸载
- DOM 已销毁
🎯 三、执行顺序图示
scss
setup() ← 初始化 state / computed / watch
│
onBeforeMount() ← 挂载前
│
DOM 渲染
│
onMounted() ← 挂载完成,可操作真实 DOM
│
响应式数据变化
│
watch() ← flush: pre/post/sync 执行
│
用户操作 / 卸载组件
│
onBeforeUnmount()
│
onUnmounted()
🎯 四、代码示例
xml
<script setup>
import { ref, watch, onMounted, onBeforeUnmount } from 'vue'
const count = ref(0)
watch(count, (newVal) => {
console.log('watch count:', newVal)
}, { flush: 'post' })
onMounted(() => {
console.log('mounted')
})
onBeforeUnmount(() => {
console.log('beforeUnmount')
})
setTimeout(() => count.value++, 1000)
</script>
输出顺序:
yaml
mounted
watch count: 1 ← flush: post,DOM 已更新
beforeUnmount ← 卸载组件时
🎯 五、面试官常见追问
追问 1:watch flush 参数含义?
'pre'(默认) → 在 DOM 更新前执行'post'→ 在 DOM 更新后执行'sync'→ 同步执行,立即触发
追问 2:setup 内 watch 和生命周期执行顺序?
- setup 先执行
- 生命周期注册在 setup 后,但会在挂载阶段依次触发
- watch flush
'pre'在 onMounted 前可能执行一次(第一次访问依赖会立即触发)
追问 3:onMounted 中可以访问 DOM 吗?
- ✅ 可以
- 因为组件已经挂载完成
- 在 setup 或 onBeforeMount 中访问 DOM 是 null
追问 4:onBeforeUnmount 与 watch 清理有关系吗?
- watch 可返回 stop 函数
- 在 onBeforeUnmount 中调用 stop() 可手动停止 watch
- 避免组件卸载后副作用仍然触发
🎯 六、一句话总结
Vue3 生命周期顺序:
setup → onBeforeMount → onMounted → 响应式 watch → onBeforeUnmount → onUnmounted;watch flush 决定响应式回调执行时机,可精确控制 DOM 更新前后。