watchEffect 立即执行回调并自动追踪其中用到的响应式依赖,依赖变化就重跑;watch 需显式指定监听源,惰性执行,能拿到新旧值,支持 deep、flush 等选项。经验法则:需要精确控制监听什么、需要新旧值对比用 watch;只是「依赖变了就重跑副作用」用 watchEffect。

易错点:watch 监听 reactive 对象的属性要传 getter:watch(() => obj.a, cb),直接传 obj.a 是静态值不会触发;deep: true 遍历开销大,大对象慎用。副作用清理用回调参数的 onCleanup(3.5+,旧名 onInvalidate)解决竞态——连续输入触发多次请求时取消上一次。flush: 'post' 可在 DOM 更新后执行。追问:pre/post/sync 三种调度时机、与 computed 的边界——纯派生用 computed,有副作用才用 watch。

watch(keyword, async (val, old, onCleanup) => {
  const ctrl = new AbortController()
  onCleanup(() => ctrl.abort())
  await search(val, { signal: ctrl.signal })
})