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,滚动是动作。
相关推荐
啦啦9118867 分钟前
【版本更新】Edge 浏览器 v142.0.3595.94 绿色增强版+官方安装包
前端·edge
蚂蚁集团数据体验技术26 分钟前
一个可以补充 Mermaid 的可视化组件库 Infographic
前端·javascript·llm
LQW_home35 分钟前
前端展示 接受springboot Flux数据demo
前端·css·css3
q***d17341 分钟前
前端增强现实案例
前端·ar
IT_陈寒42 分钟前
Vite 3.0 重磅升级:5个你必须掌握的优化技巧和实战应用
前端·人工智能·后端
JarvanMo1 小时前
Flutter 3.38 + Firebase:2025 年开发者必看的新变化
前端
艾斯比的日常1 小时前
JVM 内存结构:全面解析与面试重点
jvm·面试·职场和发展
Lethehong1 小时前
简历优化大师:基于React与AI技术的智能简历优化系统开发实践
前端·人工智能·react.js·kimi k2·蓝耘元生代·蓝耘maas
gadiaola1 小时前
【计算机网络面试篇】HTTP
java·后端·网络协议·计算机网络·http·面试
华仔啊1 小时前
还在用 WebSocket 做实时通信?SSE 可能更简单
前端·javascript