Vue中的watch和watchEffect
Vue 中两个侦听副作用 API 的区别、使用场景与边界。
#tech / dev / frame
#resource / vue3
#type / concept
#status / growing
[!info] related notes
- 所属 MOC: Vue MOC
- 上位主题: Vue 响应式系统
- 前置概念: Vue中的ref和reactive, vue-computed
- 对照理解: react-use-effect
- 相关机制: vue-render-and-update-flow, vue-next-tick
Vue中的watch和watchEffect
watch 和 watchEffect 都用于响应状态变化后的副作用,但它们对依赖的声明方式不同。
一句话定义
watch是显式监听watchEffect是自动收集依赖
为什么这组 API 容易被误用
因为很多人会把:
- 派生状态
- 副作用
- 自动更新
这三件事混成一件事。
但更稳的边界应该是:
- 要“得到一个值”优先想
computed - 要“在变化后做点事”才考虑
watch/watchEffect
watch 的特点
- 监听源明确
- 可以拿到新值和旧值
- 更适合精确控制触发条件
watch(count, (newVal, oldVal) => {
console.log(newVal, oldVal)
})
watchEffect 的特点
- 会立即执行一次
- 自动收集回调中访问到的响应式依赖
- 更适合快速声明一段响应式副作用
watchEffect(() => {
console.log(count.value)
})
什么时候用 watch
- 需要拿到
oldValue - 只想监听特定来源
- 你要做请求、同步、日志、持久化等副作用
什么时候用 watchEffect
- 依赖比较分散,不想手写依赖源
- 快速建立一个自动同步的副作用
- 这段逻辑天然应该先执行一次
一个更直观的对照
watch 更像:
- 我知道我要盯谁
- 我想精确控制监听来源
watchEffect 更像:
- 你帮我自动收集回调里访问到的依赖
- 我更关心“这段副作用和哪些响应式值有关”
和 React 的一个关键差异
如果对照 React:
watchEffect有点像自动依赖收集版本的副作用- React 的
useEffect更强调手写依赖数组
这也是很多人从 Vue 切到 React 时,最容易在 effect 依赖上踩坑的原因。
和 computed 的边界
如果你只是想推导一个值,优先用 vue-computed;只有当你真的要“在变化后做点事”,才进入 watch / watchEffect。
和更新流程的关系
它们通常不是直接负责渲染本身,而是挂在响应式变化之后,处理渲染之外的副作用。
常见误区
- 用侦听器保存本来可以直接
computed的值 - 在回调里反复修改监听源自己,造成循环触发
- 把副作用和渲染逻辑混在一起
最短记忆方式
watch:我知道我要盯谁watchEffect:你帮我收集依赖
面试要点
来自 vue-watch-vs-watch-effect-interview-question 的面试视角整理。
一句话回答
watch 需要你明确指定监听源,更适合精确控制;watchEffect 会自动收集回调里用到的响应式依赖,更适合快速声明一段副作用。
最稳的回答主线
watch:监听源明确,可拿新旧值watchEffect:自动收集依赖,默认先执行一次- 两者都适合副作用,不适合替代
computed
最短记忆方式
watch 是我指定依赖,watchEffect 是你帮我找依赖。