🧠 Vue watch
vs watchEffect
全面对比
🎯 一句话区别(面试口语版)
watch
更像是“观察一个明确的数据源”,而watchEffect
是“自动收集依赖,只要访问了响应式数据就会触发”。
✅ 一、定义与语法
特性 | watch | watchEffect |
---|---|---|
是否自动收集依赖 | ❌ 否,需显式指定依赖源 | ✅ 是,自动追踪同步访问的响应式依赖 |
主要用途 | 响应某个特定数据源的变化,常用于副作用(如请求) | 处理副作用逻辑,自动追踪依赖 |
回调参数 | (newVal, oldVal, onCleanup) | (onCleanup) (不能拿到 new/old 值) |
支持懒执行 | ✅ 默认懒执行,immediate: true 可立即执行 | ❌ 默认立即执行 |
可用于异步逻辑 | ✅ 支持良好,结合 onCleanup() 使用 | ✅ 支持良好,适合轻量副作用逻辑 |
清理副作用 | ✅ onCleanup(fn) | ✅ onCleanup(fn) |
✅ 二、使用示例对比
watch 示例(显式依赖):
watch(() => props.id, (newVal, oldVal) => {
fetchData(newVal)
})
watchEffect 示例(自动依赖):
watchEffect(() => {
fetchData(props.id) // 只要 props.id 改变就重新执行
})
✅ 三、依赖收集机制
特性 | watch | watchEffect |
---|---|---|
响应式追踪范围 | 只追踪 getter 函数的返回值 | 追踪函数体内同步访问的所有响应式数据 |
支持深层调用链 | ✅,getter 中访问深层响应式数据会被追踪 | ✅,只要访问了响应式数据就会被追踪 |
异步代码内访问响应式 | ❌ 不追踪 | ❌ 不追踪 |
✅ 四、典型应用场景
🔹 watch
适用场景:
- 明确监听某个响应式值,如:props、路由参数等
- 希望拿到
newVal / oldVal
- 想要懒触发副作用,或手动控制执行时机
🔹 watchEffect
适用场景:
- 响应式数据可能有多个来源
- 快速实现响应式副作用,如自动 fetch、同步 DOM
- 更像是
computed
+watch
的组合
✅ 五、陷阱 & 注意事项
情况 | watch | watchEffect |
---|---|---|
异步中访问响应式值不会被追踪 | ❗ 不会 | ❗ 不会 |
改变的值是深层对象字段 | 需要 deep: true | 自动追踪,除非被异步隔开 |
第一次是否执行 | 默认不执行,需配置 | 默认立即执行 |
cleanup 清理副作用的时机 | 下一次执行前或组件卸载 | 同左 |