watchEffect 是 Vue 3 中自动追踪响应式依赖并立即执行的副作用函数,无需手动声明依赖;它通过 ReactiveEffect 在 getter 中收集实际读取的字段,支持条件分支与深层属性捕获,但不支持 deep 配置,适合轻量、聚焦的响应逻辑。

watchEffect 是 Vue 3 中真正“写完就跑”的响应式工具——你只管在函数里读响应式数据,Vue 自动盯住它们,一变就重执行,连依赖数组都不用列。
自动追踪怎么发生的?
它靠 Vue 的 ReactiveEffect 机制实现:首次执行副作用函数时,每次访问 ref.value 或 reactive 对象属性,都会触发 getter,系统悄悄记下“这次用了谁”;后续这些值被修改(setter 触发),就立刻重跑整个函数。
- 只追踪实际读取的响应式字段,比如
if (show) { user.name },show 为 false 时 user.name 不会进依赖列表 - 嵌套对象深层属性(如
user.profile.avatar)也能被精准捕获,但 不支持 deep: true 配置,要监听整个对象变化得用 watch - 组件卸载时自动停止监听,不用手动调用
onUnmounted清理
副作用函数里该做什么?
适合“值一变就立刻反应”的轻量逻辑,比如更新 UI 状态、打日志、触发请求。关键是要让副作用保持聚焦、可预测。
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
- 避免在函数内直接修改被追踪的响应式数据,否则可能引发无限循环(Vue 会报 warning)
- 分支逻辑中未执行的代码路径,其内部响应式读取不会被收集,依赖是动态且精确的
- 如果需要 DOM 更新后操作(比如读取元素尺寸),用
flush: 'post',确保拿到真实渲染结果
异步任务怎么安全处理?
频繁变动状态时,旧请求还没返回、新请求又发出去了,容易覆盖结果或浪费资源。watchEffect 提供 onInvalidate 机制,在下一次执行前帮你清理上一轮未完成的任务。
立即学习“前端免费学习笔记(深入)”;
- 在发起请求或启动定时器之前,注册清理函数,比如
onInvalidate(() => controller.abort()) - 不要在函数开头就
await fetch(...),否则阻塞后续变更响应;推荐用 AbortController 或递增 ID 标记来判断响应是否还有效 - 清理函数本身必须同步执行,不能是 async,但可以取消 Promise、清除 timer、移除事件监听
什么时候该换用 watch?
watchEffect 简洁有力,但不是万能钥匙。以下情况更适合 watch:
- 需要对比新旧值做差异判断(如仅当 name 从空变非空才发请求)
- 监听计算属性的 getter,或依赖多个来源组合(比如路由参数 + 用户权限)
- 必须深层监听对象所有变化,或要求
immediate: true+deep: true组合

















