Vue3与vue2响应式处理的不同
# ✅ 一张表总结差异
| 数据类型 | Vue2 响应式处理 | Vue3 响应式处理 | 根本区别 |
|---|---|---|---|
| Object | Object.defineProperty 劫持属性 | Proxy 拦截所有操作 | Vue3 更完整、更快,支持深层操作 |
| Array | 仅重写 7 个变更方法,无法监听索引和 length | Proxy 可监听 所有操作 | Vue2 监听能力严重不足,Vue3 完整 |
| Map | ❌ 不支持 | ✔ 完整支持:get/set/has/delete/clear/遍历 | Vue2 无法处理,Vue3 可响应复杂数据结构 |
| Set | ❌ 不支持 | ✔ 完整支持:add/delete/clear/遍历 | Vue2 无法处理,Vue3 支持迭代依赖追踪 |
| WeakMap / WeakSet | ❌ 不支持 | ✔ 支持(但弱集合不触发依赖) | 用于内部缓存 |
| 依赖追踪 | 只能追踪属性 getter | 可追踪任意行为:迭代、size、keys、values | Vue3 的能力远超过 Vue2 |
| 性能 | 大量开销,对象越大越慢 | Proxy 常数时间 | Vue3 在大数据结构下优势明显 |
# ✨ 重点差异逐条解析
# 1. Vue2 的响应式系统无法完美代理数组
# Vue2 只能做两件事:
- 对数组元素做
defineProperty→ 只能侦测已有索引 - 覆盖数组变更函数:
push
pop
shift
unshift
splice
sort
reverse
1
2
3
4
5
6
7
2
3
4
5
6
7
# ❌ Vue2 无法监听的情况
下面这些 Vue2 全部监听不到:
arr[3] = 123 // 无法监听新增索引
arr.length = 1 // 无法监听 length 变化
1
2
2
👉 因为 defineProperty 没法拦截索引变化,也无法劫持 length。
# ✔ Vue3 的数组方案完全不同:使用 Proxy
Vue3 使用:
Proxy(target, {
get,
set,
has,
ownKeys,
deleteProperty,
})
1
2
3
4
5
6
7
2
3
4
5
6
7
所以数组的所有行为都能被拦截:
# Vue3 可监听所有情况:
arr[3] = 123 // ✔ 能监听
arr.length = 1 // ✔ 能监听
for (let i of arr) // ✔ 遍历依赖建立
Object.keys(arr) // ✔ ownKeys 拦截
1
2
3
4
2
3
4
👉 这让 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 API | Vue3 是否响应式支持 |
|---|---|
| get | ✔ 建立依赖 |
| set / add | ✔ 触发更新 |
| delete | ✔ |
| clear | ✔ |
| forEach | ✔ |
| entries/keys/values | ✔ |
| size | ✔ 会触发更新 |
# 示例:Vue3 的 Map 是响应式的
const m = reactive(new Map())
m.set("name", "vue") // 触发更新
m.get("name") // 建立依赖
m.delete("name") // 触发更新
1
2
3
4
5
2
3
4
5
甚至:
for (const [k,v] of m) {
// 也会建立迭代依赖
}
1
2
3
2
3
# 4. Vue3 多了“迭代依赖”的概念,这是 Vue2 做不到的
Vue3 对这类操作也会建立依赖:
for...of
for...in
Object.keys()
Object.values()
Object.entries()
map.forEach()
map.size
1
2
3
4
5
6
7
2
3
4
5
6
7
这在 Vue2 是根本不存在的。
# 5. weak collections(Vue3 新增支持)
Vue3 也支持:
WeakMap
WeakSet
1
2
2
但要注意:
- 因为其中 key 是弱引用,所以依赖不会持久保存
- 内部常用于缓存,例如 track/trigger 的依赖表
# 🎯 核心总结(面试够用)
# Vue2 vs Vue3 响应式差异本质:
| 特性 | Vue2(defineProperty) | Vue3(Proxy) |
|---|---|---|
| 可劫持范围 | 只能属性级 | 整个对象的所有操作 |
| Array | 只能劫持 7 个方法 | 所有操作 |
| 新增属性 | 无法监听 | 自动监听 |
| 删除属性 | 无法监听 | 自动监听 |
| Map / Set | ❌ 无法监听 | ✔ 完整支持 |
| 迭代依赖 | ❌ 不支持 | ✔ 支持 |
| 深层结构 | 性能差 | 快 |
| 大量对象 | 初始化极慢 | 性能好 |
# 📌 总结一句话
Vue3 的响应式系统是从根本上重写的;数组、Map、Set 都实现了完全响应式,而 Vue2 只能勉强支持对象和部分数组 API。
上次更新: 2025/12/10, 08:07:53