前端进阶之旅前端进阶之旅
  • 基础篇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 多个来源数组 newValues oldValues
VuVue侦听与生命周期

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

来源数组中的每一项应是可观察入口,回调的新旧值按相同位置组成数组。

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

让共同决定操作的输入保持清楚

  1. 来源定义页码 ref 与筛选字段 getter 分别占一个位置
  2. 参数对应newValues 和 oldValues 的相同索引指向同一来源
  3. 共同处理一次回调围绕当前有效输入执行对应同步

动态增删来源时需要重新设计监听生命周期,不应让数组位置悄悄改变字段含义。

核心回答

先记住这个答案

watch 可以接收 ref、响应式对象和 getter 组成的来源数组。某个有效来源变化后,回调获得按来源顺序排列的新值数组与旧值数组,因此可以在同一处处理共同决定请求的输入。应传入 ref 本身或字段 getter,而不是提前读取出的普通值。多个同步修改可能被批量调度成一次回调,数组中的对象也不是自动深克隆的历史快照。

  • 来源顺序决定新旧参数的对应位置
  • 字段原始值应通过 getter 提供持续读取入口
  • 同一轮同步修改可能合并,回调不等于逐赋值日志

页码与筛选状态可以在同一回调中处理

一个列表请求由 page 和 status 决定,分别写两个监听器可能重复实现请求、取消和错误处理。来源数组可以集中描述这两个输入,让回调拿到当前组合。这个组织方式并不自动保证请求只发送一次,还要考虑输入重置与异步竞争,但至少减少两条同步逻辑的重复维护。

例如筛选变化时还要把页码重置为一,应明确这是一组业务状态转换,避免先请求新筛选下的旧页码,再在另一个回调里修正页码引起第二次请求。可以在同一事件或状态更新入口中表达相关变化,再让同步逻辑处理最终输入。

代码中的来源和参数按位置一一对应

下面监听 page ref 和 filters.status getter,连续修改两者后等待下一次调度完成,再查看记录。示例使用默认调度,展示同一轮同步变化可以形成一次回调;它没有用同步 flush 将每次赋值强行拆开,也没有执行网络请求。

如果把第二项写成 filters.status,传进去的只是当时字符串,后续无法凭它继续读取字段。若数组中包含对象来源,旧参数也可能与新参数共享对象引用,不能因为外层是两个数组就假定内部已经有独立历史。需要旧字段数值时,应选择对应的原始值 getter。

默认调度合并同一轮多个来源变化TypeScript
import { nextTick, reactive, ref, watch } from 'vue';

const page = ref(1);
const filters = reactive({ status: 'open' });
const records: Array<{ next: unknown[]; previous: unknown[] }> = [];
const stop = watch([page, () => filters.status], (next, previous) => {
  records.push({ next: [...next], previous: [...previous] });
});

page.value = 2;
filters.status = 'closed';
await nextTick();
stop();

在支持顶层 await 的 Vue 模块环境中,records 包含一条记录:next 为 [2, closed],previous 为 [1, open]。这两项都是原始值,代码没有控制台输出。

来源数量增加后仍应保持业务边界

只有共同决定同一副作用的输入才值得放在一起。把主题、文档、鼠标位置和表单错误全装成一个来源数组,会让回调的触发条件越来越难解释。无关同步可以拆成独立过程,各自管理需要的资源与清理,而不是依赖位置很多的数组作为万能事件总线。

回调如果发请求,需要保留本轮参数并处理迟到结果;不能在请求完成时再从全局读取可能已经变化的 ID,然后把旧结果当成新请求结果。对输入组合建立明确的请求键或版本,有助于取消、缓存与验收。数组 API 只是提供来源关系,不会自动解决这些异步协议。

回答前,多想一步

容易答错的地方

数组里写任意字段值都能自动追踪
普通原始值只是一张快照。要让 Vue 后续重新读取,应提供 ref、响应式对象或 getter,并注意对象入口与属性替换的区别。
新旧参数是不同数组,所以其中对象也是独立快照
外层数组不同不意味着嵌套对象被克隆。需要完整历史时应单独设计快照;只关心少量原始字段时直接监听那些字段更清楚。
试着用自己的话回答

面试官还会怎么问?

两个来源同一轮变化一定执行两次吗?

默认调度可能将同步变化合并,回调看到这一轮的最终组合;同步 flush 或跨调度轮次则可能不同。业务不能把来源数量当成固定回调次数。

immediate 首次多源回调有完整旧值数组吗?

没有此前观察结果时,不能假定每个旧位置都已有业务值。应按初始化情况处理,而不是无条件读取旧对象字段或用旧数组长度证明有历史。

监听来源数组与 getter 返回数组一样吗?

不完全一样。前者把每一项当作独立来源解析,后者是一个 getter 的返回结果,新的数组引用会影响结果比较;应按实际想表达的变化关系选择。

从一道题,走向一组知识

把知识连起来

侦听与生命周期

Vue watch 的 getter 返回新对象,为什么仍可能不触发或触发过多?

getter 返回新对象或数组时,还要理解结果身份如何扩大回调范围。

侦听与生命周期

Vue 深度 watch 的 oldValue 和 newValue 为什么是同一个对象?

数组中的对象仍可能共享引用,继续区分旧引用和旧内容。

参考资料

  • Reactivity API: watch
  • Watchers: Callback Flush Timing

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

本题目录
  1. 先记住这个答案
  2. 页码与筛选状态可以在同一回调中处理
  3. 代码中的来源和参数按位置一一对应
  4. 来源数量增加后仍应保持业务边界
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

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

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