前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库Vue watch 监听源 ref reactive getter 区别
VuVue侦听与生命周期

Vue watch 监听 ref、reactive 对象和 getter 时有什么区别?

先看传给 watch 的是什么来源,再判断它会观察整体替换、具体字段还是整个响应式对象。

前端进阶之旅 · 一题精讲更新于 2026.09.06
Vue#侦听与生命周期
先看核心答案
理解线索

把监听目标写成可解释的输入关系

  1. 值容器ref 提供稳定入口,内部值替换可被观察
  2. 对象范围直接 reactive 对象监听会观察其深层变化
  3. 明确取值getter 表达某字段或纯派生结果作为监听目标

watch 与 watchEffect 的依赖收集方式不同,不能把 watch 回调内的所有读取都当成自动订阅。

核心回答

先记住这个答案

watch 可以接收 ref、响应式对象、getter 或这些来源的数组。ref 通常观察它的 value 变化,直接监听 reactive 对象具有默认深层观察行为,getter 则追踪执行时读取的响应式来源,并根据返回值判断变化。watch(state.count, callback) 若传入的是普通数字,就没有提供后续可读取的来源;应使用 getter 或字段 ref。选择监听源应尽量准确表达副作用真正依赖的数据。

  • ref、响应式对象与 getter 有不同的默认观察范围
  • 普通原始值不是能持续读取变化的监听源
  • watch 回调读取其它字段不会自动把它们变成监听源

同一字段可以通过不同入口被观察

例如页面有一个 page ref、一个 filters reactive 对象,以及由两者形成的请求键。监听 page 适合观察页码变化;直接监听 filters 会包含较宽的对象变化范围;监听 getter 返回的请求键,则可以把触发条件压缩为请求真正需要的组合结果。没有一种写法天然适合所有副作用。

如果只关心 filters.status,getter 可以直接返回这个字段,让其它筛选配置变化不必触发相同逻辑。反过来,getter 只返回 filters 对象引用时,不能期待默认行为自动观察它内部所有字段;需要深层观察时应明确表达,或者直接选择对象监听并接受对应范围。

传入原始属性值为什么无法持续观察

调用 watch 时先求值 state.count,得到的是那一刻的数字。数字本身不知道它从哪个对象属性而来,watch 也就无法凭它重新访问源字段。用 () => state.count 延迟读取,或者使用 toRef(state, "count"),才能把来源关系留给响应式系统。

但若 state.child 本身就是一个响应式对象,直接传给 watch 可以观察那个对象的内部变化。这里还要考虑父对象以后是否替换 child:监听旧对象与监听父对象上的 child 入口不同。不能把原始值无效的结论扩展成所有属性都绝对不能直接传。

副作用输入越准确,竞争与成本越容易处理

请求只依赖文档 ID,就不要因为展示主题或草稿光标变化也重新请求。可以让 watch source 返回明确 ID,回调中处理请求取消、错误与迟到结果。回调偶尔读取日志配置并不自动改变监听源,若配置变化本身也需要重跑,就应把它明确纳入来源。

默认回调调度会批量处理同步更新,不能把每次字段赋值都算成一次独立回调。测试时应区分一次状态转换与最终调度结果。需要读取更新后的 DOM 时再考虑对应 flush 时机;监听源决定观察什么,调度选项决定何时执行,两者应分别讨论。

回答前,多想一步

容易答错的地方

watch 回调里用了哪个字段,就会监听哪个字段
这是把 watch 与自动收集回调读取的 watchEffect 混淆。watch 的依赖入口是显式 source,回调读取并不会自动扩展它的观察范围。
getter 只要被声明,就会随组件每次渲染执行回调
watch 根据响应式来源变化运行相关判断,不是组件的通用渲染回调。无关组件更新不能自动代替 source 的变化通知。
试着用自己的话回答

面试官还会怎么问?

可以一次监听多个来源吗?

可以传来源数组,例如一个 ref 加一个字段 getter,回调的新旧值也按位置组成数组。数组里的原始字段快照仍不能冒充有效的动态来源。

ref 保存对象时,内部字段变化默认会触发吗?

普通监听该 ref 通常关注 value 的变化,内部字段修改需要深层选项或更具体的字段 getter。对象本身具有响应式能力,不等于所有监听入口默认都深度遍历。

只是计算展示结果也应该 watch 吗?

通常先考虑 computed 或直接纯计算。watch 适合变化后需要执行外部同步或其它明确副作用的场景,额外保存可派生值会增加同步成本。

从一道题,走向一组知识

把知识连起来

侦听与生命周期

为什么直接 watch reactive 对象默认深监听,而 watch ref 对象的表现不同?

进一步区分直接监听对象与监听返回对象的 getter 的默认深度。

侦听与生命周期

Vue watch 怎样监听多个来源,新旧参数数组如何对应?

多个输入共同决定副作用时,可以使用来源数组表达完整关系。

参考资料

  • Reactivity API: watch
  • Watchers

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 同一字段可以通过不同入口被观察
  3. 传入原始属性值为什么无法持续观察
  4. 副作用输入越准确,竞争与成本越容易处理
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑