Vue响应式系统通过精准依赖追踪、局部通知和批量刷新协同实现高效部分更新,仅重渲染受影响组件,避免全量重算与无谓开销。

依赖路径必须可追踪,否则更新会失效
部分更新生效的前提是:模板或逻辑中对数据的访问方式必须能被 Proxy 或 defineProperty 捕获为独立依赖路径。
- ✅ 正确写法:
list.value[5].name = 'Alice'(list是 reactive 数组,且第 6 项本身是响应式对象)—— Vue 能定位到具体项和字段,只触发关联组件重渲染 - ❌ 错误写法:
const item = list.value[5]; item.name = 'Alice'—— 解构后丢失响应式连接,变更不被追踪 - ⚠️ 注意数组索引赋值:Vue 3.2+ 的
reactive([])支持直接arr[i] = newVal;但ref([])仍需用arr.value.splice(i, 1, newVal)或展开赋值
只更新真正变化的字段,不扩散无关依赖
Vue 不会因为一个对象里某个字段变了,就让整个组件重新 render。它记录的是“谁读了哪个 key”,所以:
- 若模板只用了
{{ user.name }},那修改user.email完全不影响该组件 - 计算属性
computed(() => items.filter(x => x.active))只依赖items和每个item.active,改其他字段不触发重算 - watch 监听
() => state.count,不会因state.message变化而执行回调
批量异步调度,合并同一轮中的多次变更
即使你连续修改 100 个不同项,只要在同一个同步任务内完成,Vue 也只做一次 DOM 更新:
- 每次 setter 触发后,对应 Watcher 被推入队列,但去重机制确保相同组件只进一次
- 队列在 microtask 阶段统一 flush,按组件层级排序(父优先),避免子组件读取旧 props
- 这意味着
for (let i = 0; i 不会导致 100 次 patch,而是一次整体 diff
大规模场景下推荐的轻量协作策略
响应式系统再快,也不建议把 10 万条原始数据全塞进 reactive。真正高效的部分更新,往往靠“分层解耦”:
立即学习“前端免费学习笔记(深入)”;
- 用 markRaw 包裹只读大数据:如日志列表、原始表格 JSON,避免 Proxy 代理开销
-
响应式只管“视图元数据”:比如
visibleIds: ref(new Set([1,2,3]))、filters: ref({ status: 'active' }),再由 computed 派生当前页数据 - 虚拟滚动配合局部响应:vue-virtual-scroller 只激活可视区域几十条数据的响应式状态,滚动时动态切换,而非全量监听
-
服务端聚合后再传前端:不要前端
.map().filter().sort()百万级数组,让 API 返回已筛选/分页/结构化好的结果


















