Vue3 响应式革命

Vue2 验证了「响应式驱动视图」的威力,却在数组索引、属性增删等场景留下无法追踪的死角。Vue3 并未缝缝补补,而是把整座大厦的地基------数据拦截机制------彻底替换为 Proxy。本文沿着「拦截 → 创建 → 收集」三条链路,带你读懂这一次底层跃迁的全部细节。

一、拦截:从点到面的语义升级

1.Vue2 的「定点拦截」

Object.defineProperty 只能劫持已存在的属性。当业务代码 obj.newKey = 1 时,这条新增路径对依赖系统完全不可见,于是官方只能额外暴露 Vue.set / vm.$set 作为补丁。

2.Vue3 的「整面拦截」

Proxy 把「对象」视为一个整体,任何对属性的 读取、写入、删除、遍历 乃至 原型链读取 都能被捕获。

ts 复制代码
const p = new Proxy(obj, {
  get(target, key, receiver) { /* 读 */ },
  set(target, key, value, receiver) { /* 写 */ },
  deleteProperty(target, key) { /* 删 */ }
})

新增 key 不再逃逸,数组索引与 length 的变化自然落入监听范围,彻底告别 $set

二、创建:ref 与 reactive 的分工

虽然 Proxy 能力更强,但「原始值」无法被代理。Vue3 用 RefImpl 与 ReactiveImpl 两套实现互补:

  • ref 负责原始值(Number、String、Boolean)------内部用 RefImpl 包裹,读/写时触发自定义 getter/setter;当值是对象时再递归交给 reactive
  • reactive 负责对象/数组------直接返回 Proxy,拦截全部操作。

源码片段(精简):

ts 复制代码
class RefImpl<T> {
  get value() {
    track(this, 'value')   // 收集
    return this._value
  }
  set value(newVal) {
    this._value = toReactive(newVal)
    trigger(this, 'value') // 派发
  }
}

function reactive(target: object) {
  return createReactiveObject(target, mutableHandlers)
}

toReactive 判断传入值是否为对象,是则继续包 Proxy,否则原样返回,形成一条「层层代理,按需终止」的链。

三、收集:从 Watcher 树到副作用图

1.Vue2 的 Watcher + Dep

每个响应式属性拥有一个 Dep,Dep 里存着若干 Watcher(通常是一个组件渲染函数)。属性变化 → 通知所有 Watcher → 组件级重渲染。

粒度:组件级别。

2.Vue3 的副作用图

Vue3 不再关心「是哪个组件」,而是关心「哪个副作用函数」。数据结构是一张 WeakMap → Map → Set 的三级表:

  • 第一级 WeakMap:键是响应式对象,值是第二级 Map;
  • 第二级 Map:键是属性名,值是第三级 Set;
  • 第三级 Set:存储所有依赖该属性的 effect 函数。

当属性值改变时,只触发 精确到函数 的重新执行,粒度从组件级降到函数级,更新范围更小,性能更高。

四、工程实践的迁移

  • Vue2 项目:若观察到大量 this.$setVue.set,说明已踩中响应式盲区,升级 Vue3 可一次性消除。
  • 新 Vue3 项目:优先使用 reactive 管理对象,ref 管理原始值;避免把 reactive 包进 ref,防止双重代理带来的额外开销。
  • 性能调优:借助 markRawshallowReactive 把大列表、第三方库实例标记为非响应式,减少追踪压力。

结语

Vue3 的响应式不是「打补丁」,而是「换引擎」。Proxy 让「增删改查」全部可追踪,WeakMap 让依赖收集更精准。这次底层跃迁,彻底解决了 Vue2 的响应式难题,也为 Vue3 的性能优化奠定了基础。

相关推荐
BigTopOne4 小时前
【WebRtc】DTLS-SRTP 加密完整流程详解
前端
陈随易4 小时前
pm2 替代品,nodejs&bun 线上部署必备工具
前端·后端·程序员
单线程_014 小时前
从案例分析 Vue3 Tokenizer 源码一
前端·javascript·vue.js
BigTopOne5 小时前
【WebRtc】-ICE Candidate 与 STUN/TURN 原理详解
前端
l1258655 小时前
# LangGraph Memory机制深度解析:短期记忆与长期记忆的工程实践
前端·人工智能·python·langchain·bootstrap
码视野5 小时前
基于 Spring Boot + Vue3 的【大学英语四六级 (CET-4/6) 作文智能评分与句式润色系统】设计与实现(含PRD/三端高保真源码/大屏)
java·前端·人工智能·spring boot·后端·vue3
大模型码小白5 小时前
AI 对话流性能调优:万级消息的虚拟滚动落地
java·大数据·前端·javascript·人工智能·算法·机器学习
数智启示录6 小时前
Flink CDC 机制精讲(二):Checkpoint Barrier 如何形成一致快照 【面试宝典】
大数据·经验分享·面试·flink
xm_xm_xm_16 小时前
react17版本以前类组件常用操作
前端·javascript·react.js
ly76897 小时前
Web 性能优化实战:从 Core Web Vitals 到工程化性能治理
前端·性能优化