最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
watchEffect 侦听器:如何自动追踪响应式依赖
时间:2026-07-12 10:58:52 编辑:袖梨 来源:一聚教程网
watchEffect会自动追踪函数中读取的响应式数据,定义时立即执行,变化时自动重跑,无需手动指定依赖或配置immediate,内部通过getter/setter拦截实现依赖收集与响应。
watchEffect 会自动追踪你函数里“读取过”的响应式数据,一定义就执行,一变化就重跑,不用列依赖、不用配 immediate: true,也不用手动清理——Vue 内部靠 getter/setter 拦截完成整个过程。
它只追踪真正被用到的响应式值
watchEffect 不是扫描变量名,而是在函数执行时实时记录哪些响应式属性被访问了:
- 写了
count.value和user.profile.name,就只盯这两个; - 用了
if (show) { data.list },只有show为真时,data.list才进依赖; - 普通变量、常量、非响应式对象属性,哪怕写在同一行,也不会被追踪;
- 赋值操作(如
count.value = 5)本身不触发依赖收集,只有读取才收集。
首次运行即生效,后续变化自动响应
定义 watchEffect 的那一刻,函数就同步执行一次,相当于内置了 immediate: true。之后只要它内部读取过的响应式值变了,就会立刻再执行一遍:
- 适合初始化请求、设置定时器、同步 DOM 状态等场景;
- 组件卸载时自动停止,无需在
onUnmounted里手动调用清理; - 如果想跳过首次执行,得靠
onInvalidate配合逻辑控制,但极少需要。
异步任务要防竞态,用 onInvalidate 清理上一轮
输入搜索、滚动监听这类高频触发场景,容易出现“旧请求还没回来,新请求又发了”。watchEffect 提供 onInvalidate 回调,在下一次执行前自动调用:
- 在函数开头注册:
onInvalidate(() => clearTimeout(timer)); - 发起 fetch 时用
AbortController,新请求前调abort(); - 清理函数必须在异步操作启动前注册,否则可能清理不到正在运行的任务。
什么时候该换用 watch?
watchEffect 简洁高效,但不是万能:
- 需要对比新旧值(比如只在从空变非空时触发)→ 选
watch; - 要监听深层嵌套对象任意字段变化(
deep: true)→watchEffect不支持; - 依赖来源分散、或含计算属性 getter 异常判断 →
watch更可控; - 只是把响应式数据加工成另一个响应式值 → 优先用
computed。