---
description: Vue 响应式优先使用 computed，谨慎使用 watch
alwaysApply: true
---

# Vue：Prefer computed over watch

## 一句话规则

能用 `computed` 实现，就不要用 `watch`；`watch` 仅用于副作用或外部系统同步。
副作用优先在显式事件回调中触发；仅当无法显式建模时，才使用 `watch` 承担副作用。

## 选择顺序（按此判断）

1. 这是“值到值”的派生吗？是 -> `computed`
2. 这是“变化后要做动作”吗（请求/跳路由/打点/DOM/存储）？是 -> `watch`/`watchEffect`
3. 两者都不是 -> 优先重构数据流，避免堆叠 `watch`

## 为什么这样做

- `computed` 声明式、可推导、可缓存，维护成本低。
- `watch` 天然偏副作用，链路更隐式，调试成本更高。
- 响应式状态常有多处修改来源（业务逻辑/组件库/异步回填），`watch` 过多时很容易失控。

## 实践要求

- 纯展示状态：必须优先 `computed`。
- 使用 `watch` 时，必须满足：
  - 监听源明确（避免无必要 `deep`）。
  - 副作用目标明确（建议加 1 行注释说明触发目的）。
  - 避免在回调里同时隐式修改多个状态，降低连锁触发。

## 允许使用 watch 的典型场景

- 参数变化触发请求（含取消旧请求）
- 与路由 query / localStorage / sessionStorage 同步
- 驱动第三方 imperative API（图表、编辑器、播放器等）
- 需要 old/new 对比做流程控制

## 推荐替代思路（watch 过重时）

- `computed + 显式事件触发`
- 拆分状态来源，减少“一个 watch 做所有事”
