Glittering's blog Glittering's blog
Home
  • 学习手册

    • 《JavaScript教程》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • TypeScript
    • CSS
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)

Glitz Ma

前端开发工程师
Home
  • 学习手册

    • 《JavaScript教程》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • TypeScript
    • CSS
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)
  • vue3学习路径
  • Vue3 Virtual DOM & 渲染机制
  • Vue3 响应式核心
  • Vue3数组、Map、Set 特殊处理
  • Vue3与vue2响应式处理的不同
    • ✅ 一张表总结差异
    • ✨ 重点差异逐条解析
      • 1. Vue2 的响应式系统无法完美代理数组
      • Vue2 只能做两件事:
      • ❌ Vue2 无法监听的情况
      • ✔ Vue3 的数组方案完全不同:使用 Proxy
      • Vue3 可监听所有情况:
    • 2. Vue2 完全无法处理 Map / Set
      • ❌ Vue2 为什么做不到?
    • 3. ✔ Vue3 完整支持 Map / Set(超强)
      • Vue3 监听以下所有动作:
      • 示例:Vue3 的 Map 是响应式的
    • 4. Vue3 多了“迭代依赖”的概念,这是 Vue2 做不到的
    • 5. weak collections(Vue3 新增支持)
    • 🎯 核心总结(面试够用)
      • Vue2 vs Vue3 响应式差异本质:
    • 📌 总结一句话
  • 写一个Mini-vue
  • Mini-vue template增强版
  • 《Vue3》学习笔记
mamingjuan
2025-02-23
目录

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 只能做两件事:

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

# ❌ Vue2 无法监听的情况

下面这些 Vue2 全部监听不到:

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

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


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

Vue3 使用:

Proxy(target, {
  get,
  set,
  has,
  ownKeys,
  deleteProperty,
})
1
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

👉 这让 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

甚至:

for (const [k,v] of m) {
  // 也会建立迭代依赖
}
1
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

这在 Vue2 是根本不存在的。


# 5. weak collections(Vue3 新增支持)

Vue3 也支持:

WeakMap
WeakSet
1
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
Vue3数组、Map、Set 特殊处理
写一个Mini-vue

← Vue3数组、Map、Set 特殊处理 写一个Mini-vue→

Copyright © 2015-2025 Glitz Ma
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式