没有绝对“更好用”的那个,关键看你要解决什么问题:需对比新旧值选watch,自动收集依赖选watcheffect,控制执行时机、维护性要求高时优先watch。

没有绝对“更好用”的那个,关键看你要解决什么问题。选错反而会让逻辑变绕、性能变差,甚至埋下难以排查的响应式陷阱。
需要对比新旧值时,用 watch
比如用户权限变更、订单状态跃迁、表单字段校验依赖上一步输入——这些场景必须知道“从什么变成什么”,才能做精准判断。
- watch 回调天然接收 newValue 和 oldValue,可直接比对
- 支持 immediate: true,初始化时就能拿到初始值和 undefined(或上一次缓存值)
- 监听对象内部属性变化,加 deep: true 即可,语义清晰、控制明确
依赖多个响应式数据且不关心来源时,用 watchEffect
像搜索建议框:关键词、筛选标签、排序方式任意一个变,都要重新拉取建议列表。你不需要知道谁先动、谁后动,只要“有东西变了”就执行。
- watchEffect 自动收集回调中读取的所有响应式依赖,无需手动列出来
- 初始化时自动执行一次,省去额外触发逻辑
- 适合做副作用清理,比如在回调里打开 WebSocket,watchEffect 的清理函数会自动在下一次执行前关闭旧连接
要控制执行时机或避免过度响应,优先选 watch
高频更新的数据(如鼠标位置、滚动偏移、实时传感器值),如果用 watchEffect,每次微小变动都触发重算,容易卡顿。
- watch 可设 flush: 'post' 延迟到 DOM 更新后执行,或 flush: 'sync' 强制同步,节奏可控
- watch 支持懒执行(默认不 immediate),只在真正变化时才跑,减少无谓开销
- 监听计算属性或函数返回值时,watch 更易调试——目标明确,链路可追溯
代码可维护性要求高时,也倾向 watch
团队协作或长期迭代的项目里,别人接手时一眼得看懂“监听了啥、为啥监听、怎么响应”。watch 的显式声明就是最好的文档。
- watchEffect 的依赖是隐式的,重构时删掉某行读取语句,可能就悄悄漏掉一个监听项
- watch 的监听源写在第一个参数里,改需求时增减目标一目了然
- 类型推导更友好,TypeScript 下 watch 的 newValue/oldValue 类型通常能自动收敛,watchEffect 需额外标注










