一聚教程网:一个值得你收藏的教程网站

热门教程

watchEffect 侦听器:如何自动追踪响应式依赖

时间:2026-07-12 10:58:52 编辑:袖梨 来源:一聚教程网

watchEffect会自动追踪函数中读取的响应式数据,定义时立即执行,变化时自动重跑,无需手动指定依赖或配置immediate,内部通过getter/setter拦截实现依赖收集与响应。

watchEffect 会自动追踪你函数里“读取过”的响应式数据,一定义就执行,一变化就重跑,不用列依赖、不用配 immediate: true,也不用手动清理——Vue 内部靠 getter/setter 拦截完成整个过程。

它只追踪真正被用到的响应式值

watchEffect 不是扫描变量名,而是在函数执行时实时记录哪些响应式属性被访问了:

  • 写了 count.valueuser.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

热门栏目