watchEffect自动追踪回调中读取的所有响应式变量,任一变化即重新执行;默认浅层监听reactive对象,替换整个对象需重新读取;支持onInvalidate处理竞态;返回stop函数可手动停止监听防止内存泄漏。

watchEffect 在组合式 API 中追踪多个状态变化,核心是“自动收集依赖”——只要在回调函数里读取了多个响应式变量,Vue 就会一并追踪它们,任一变化都会触发整个回调重新执行。
直接在回调中读取多个 ref 或 reactive 属性
无需额外配置或数组包裹,把要关注的变量都写进回调里即可:
- 定义多个
ref或访问reactive对象的不同属性 - 在
watchEffect(() => { ... })的函数体中,同步读取它们的值(如count.value、name.value、user.age) - Vue 在首次执行时自动记录这些访问,后续任意一个被读取的响应式数据更新,都会重跑该函数
注意浅层追踪对 reactive 对象的影响
如果使用 reactive 对象,watchEffect 默认只做浅层追踪:
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
- 修改
user.name或user.age这类已有属性,能正常触发回调 - 但若执行
user = {...}替换整个对象,旧引用丢失,新对象需在回调中再次读取才能建立新追踪 - 不推荐依赖深层变更自动触发;如需稳定监听嵌套字段,建议用
watch配合 getter +deep: true
配合 onInvalidate 处理异步场景
多个状态频繁变化时,容易产生竞态(比如连续输入触发多次请求),可用清理机制避免副作用错乱:
立即学习“前端免费学习笔记(深入)”;
- 在回调参数中接收
onInvalidate函数 - 每次新执行前,自动调用上一轮注册的清理函数(如取消 pending 请求、清除定时器)
- 示例:
watchEffect((onInvalidate) => { const controller = new AbortController(); fetch('/api', { signal: controller.signal }); onInvalidate(() => controller.abort()); })
主动停止监听防止内存泄漏
组件卸载或条件不再需要监听时,应手动停掉 watchEffect:
- 它返回一个
stop函数,调用即终止追踪与执行 - 常见于
onBeforeUnmount或逻辑分支中:const stop = watchEffect(() => {...}); onBeforeUnmount(stop); - 尤其当回调含异步操作时,不显式 stop 可能导致组件销毁后仍尝试更新已不存在的状态

















