Skip to content

一张表总结差异

数据类型Vue2 响应式处理Vue3 响应式处理根本区别
ObjectObject.defineProperty 劫持属性Proxy 拦截所有操作Vue3 更完整、更快,支持深层操作
Array仅重写 7 个变更方法,无法监听索引和 lengthProxy 可监听 所有操作Vue2 监听能力严重不足,Vue3 完整
Map❌ 不支持✔ 完整支持:get/set/has/delete/clear/遍历Vue2 无法处理,Vue3 可响应复杂数据结构
Set❌ 不支持✔ 完整支持:add/delete/clear/遍历Vue2 无法处理,Vue3 支持迭代依赖追踪
WeakMap / WeakSet❌ 不支持✔ 支持(但弱集合不触发依赖)用于内部缓存
依赖追踪只能追踪属性 getter可追踪任意行为:迭代、size、keys、valuesVue3 的能力远超过 Vue2
性能大量开销,对象越大越慢Proxy 常数时间Vue3 在大数据结构下优势明显

1. Vue2 的响应式系统无法完美代理数组

Vue2 只能做两件事:

  1. 对数组元素做 defineProperty只能侦测已有索引
  2. 覆盖数组变更函数:
js
push
pop
shift
unshift
splice
sort
reverse

❌ Vue2 无法监听的情况

下面这些 Vue2 全部监听不到

js
arr[3] = 123   // 无法监听新增索引
arr.length = 1 // 无法监听 length 变化

👉 因为 defineProperty 没法拦截索引变化,也无法劫持 length。

✔ Vue3 的数组方案完全不同:使用 Proxy

Vue3 使用:

js
Proxy(target, {
  get,
  set,
  has,
  ownKeys,
  deleteProperty,
})

所以数组的所有行为都能被拦截:

Vue3 可监听所有情况:

js
arr[3] = 123        // ✔ 能监听
arr.length = 1      // ✔ 能监听
for (let i of arr)  // ✔ 遍历依赖建立
Object.keys(arr)    // ✔ ownKeys 拦截

👉 这让 Vue3 的数组响应式几乎和 JS 原生一致。

2. Vue2 完全无法处理 Map / Set

Vue2 的 reactivity 基于 defineProperty

  • Map 没有 key 作为属性
  • Set 没有 index
  • 没有办法监听 add/delete/clear
  • 无法捕获迭代操作(forEach, for...of

❌ Vue2 为什么做不到?

因为根本无法对 Map/Set 的行为做属性级拦截。

3. ✔ Vue3 完整支持 Map / Set(超强)

Vue3 使用 Proxy,所以可以监听 Map/Set 的所有方法。

Vue3 监听以下所有动作:

Map/Set APIVue3 是否响应式支持
get✔ 建立依赖
set / add✔ 触发更新
delete
clear
forEach
entries/keys/values
size✔ 会触发更新

示例:Vue3 的 Map 是响应式的

js
const m = reactive(new Map())

m.set("name", "vue")  // 触发更新
m.get("name")         // 建立依赖
m.delete("name")      // 触发更新

甚至:

js
for (const [k,v] of m) {
  // 也会建立迭代依赖
}

4. Vue3 多了“迭代依赖”的概念,这是 Vue2 做不到的

Vue3 对这类操作也会建立依赖:

js
for...of
for...in
Object.keys()
Object.values()
Object.entries()
map.forEach()
map.size

这在 Vue2 是根本不存在的。

5. weak collections(Vue3 新增支持)

Vue3 也支持:

js
WeakMap
WeakSet

但要注意:

  • 因为其中 key 是弱引用,所以依赖不会持久保存
  • 内部常用于缓存,例如 track/trigger 的依赖表

🎯 核心总结(面试够用)

Vue2 vs Vue3 响应式差异本质:

特性Vue2(defineProperty)Vue3(Proxy)
可劫持范围只能属性级整个对象的所有操作
Array只能劫持 7 个方法所有操作
新增属性无法监听自动监听
删除属性无法监听自动监听
Map / Set❌ 无法监听✔ 完整支持
迭代依赖❌ 不支持✔ 支持
深层结构性能差
大量对象初始化极慢性能好

📌 总结一句话

Vue3 的响应式系统是从根本上重写的;数组、Map、Set 都实现了完全响应式,而 Vue2 只能勉强支持对象和部分数组 API。