watch 与 computed:Vue3响应式的抉择

在 Vue 的响应式宇宙里,数据变化最终都会触发「副作用」:可能是重新渲染 DOM、发送网络请求,也可能是打印一条日志。Vue 提供了两条官方路线来捕获这些副作用------computedwatch。它们共享同一套依赖追踪引擎,却以截然不同的姿态服务于业务。

一、computed:把「结果」缓存成状态

想象你在做一份实时报表:销售额 = 单价 × 数量。只要单价或数量发生变化,报表必须立即更新,但你不希望每次模板读取都去重算一次。

ts 复制代码
const price = ref(100)
const count = ref(5)
const total = computed(() => price.value * count.value)

total 不是函数,而是一个「带缓存的 getter」。核心逻辑只有两步:

  • 首次读取 → 执行函数并将结果缓存;
  • 依赖变动 → 把缓存标记为「脏」,等待下一次读取时重新计算。

因此,total 永远同步、永远幂等、永远无副作用。它像数学公式一样纯粹,最适合放到模板里直接展示。

二、watch:把「动作」注册成回调

现在需求升级:当销售额首次超过 1000 时,弹一个提示,并向后端发一条记录。

这个动作需要「副作用」------弹窗与网络请求------这正是 watch 的舞台。

ts 复制代码
watch(total, (newVal, oldVal) => {
  if (newVal > 1000 && oldVal <= 1000) {
    alert('破千啦!')
    fetch('/api/record', { method: 'POST', body: newVal })
  }
})

watch 不关心结果,只关心「变化」。它把每一次变动封装成事件,允许你执行任意副作用:

  • 可以同步,也可以异步;
  • 可以读写 DOM,可以调用接口;
  • 不缓存任何结果,因为结果往往无法预测。

三、底层实现:同一条 effect,两种调度策略

无论是 computed 还是 watch,最终都会被包进同一个 effect 函数。差异体现在 调度器(scheduler):

  • computed 的调度器
ts 复制代码
  scheduler() {
    dirty = true            // 仅仅标记,不立即计算
    trigger(obj, 'value')   // 通知渲染函数
  }

它把真正的计算推迟到「下一次读取」,保证缓存生效。

  • watch 的调度器
ts 复制代码
  scheduler() {
    const newVal = effectFn()
    cb(newVal, oldValue)    // 立即执行用户回调
    oldValue = newVal
  }

它把最新值直接喂给用户回调,不缓存、不等待。

同一颗依赖追踪引擎,通过两个调度器分化出「缓存结果」与「立即动作」两条路径。

总结

用一句口诀:

  • 需要结果 → computed
  • 需要动作 → watch

具体场景举例:

  • 表单校验规则 ------ 用 computed,规则是数据推导;
  • 校验失败后高亮输入框 ------ 用 watch,高亮是副作用;
  • 根据路由参数计算面包屑 ------ 用 computed,面包屑是结果;
  • 路由变化后滚动到顶部 ------ 用 watch,滚动是动作。
相关推荐
程序员黑豆2 小时前
Java类型推断完全指南:从var到菱形运算符,掌握使用限制与最佳实践
java·前端·ai编程
To_OC2 小时前
踩了个 TS 的坑之后,我终于把 type 和 interface 掰明白了
前端·react.js·typescript
GreenTea2 小时前
深度解读 Anthropic 多智能体报告:更强的模型 ≠ 更好的协调
前端·后端·算法
码匠许师傅3 小时前
【C++ 面试真题】聊聊 C++ 的移动语义与右值引用
java·c++·面试
浮生望3 小时前
前端API工程化:用 Mock 数据与 Axios 配置实现独立于后端的并行开发
前端
万少3 小时前
给 DeepSeek Harness 装个"应用商店":一条命令,595 个插件随你逛
前端·javascript·后端
波波0073 小时前
C# 15 重磅新特性: 带标签 break 与 continue:重新定义嵌套循环控制流
服务器·前端·c#
Brown.alexis4 小时前
es6知识点1-自备使用
前端·ecmascript·es6
小爬的老粉丝5 小时前
JavaScript 纯前端预览 WPS:先识别容器,再路由解析器
前端·javascript·wps
Thecozzy5 小时前
大厂 AI Coding 面试大招
人工智能·面试·职场和发展