Vue 3 的 Map/Set 响应式需用 reactive 包裹,支持原生方法响应;key 必须是原始值或同一响应式对象;Set 变更须用 add/delete;内部值需手动 reactive 才深层响应。

Vue 3 的响应式系统(基于 Proxy)原生支持 Map 和 Set,但和 Object 或 Array 不同——它不会自动将嵌套的 Map/Set 内部元素转为响应式,也不会直接追踪其增删操作的“键名”或“值变化”,需要正确使用 API 才能触发更新。
Map 和 Set 必须用 reactive 包裹才能响应
reactive() 是处理 Map/Set 响应式的首选方式。直接用 ref() 包裹 Map/Set 虽然可行,但访问时需通过 .value,且内部方法调用(如 map.set())不会自动触发视图更新——reactive 则会代理所有原生方法并确保响应性。
- ✅ 正确:
const myMap = reactive(new Map([['a', { count: 1 }]])) - ❌ 低效:
const myMap = ref(new Map())→ 后续myMap.value.set('x', val)不触发更新(除非手动triggerRef(myMap))
Map 的 key 必须是原始值或响应式对象
Vue 3 的 reactive 对 Map 的劫持依赖于 Proxy 的 get/set/deleteProperty 拦截。如果用普通对象作 key(如 { id: 1 }),由于对象引用每次不同,Map 内部无法稳定识别,导致 has()、get() 失效或响应丢失。
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
- ✅ 推荐 key 类型:字符串、数字、Symbol、或已用
reactive()/readonly()包裹的同一响应式对象实例 - ⚠️ 注意:不要在循环中动态创建新对象作为 key —— 应提前定义并复用引用
Set 的值变更需通过 add/delete 触发,不支持直接赋值
Set 本身没有“索引”概念,也不能像数组那样通过下标修改。它的响应式更新完全依赖 add()、delete()、clear() 这些方法。若你持有 Set 中某个响应式对象并修改其属性,只要该对象本身是响应式的,视图仍会更新;但 Set 结构变化(如新增/删除元素)必须调用对应方法。
立即学习“前端免费学习笔记(深入)”;
- ✅ 正确:
mySet.add(reactive({ name: 'Alice' }))→ 新增后视图响应 - ✅ 正确:
const item = mySet.values().next().value; item.name = 'Bob'→ 若 item 是 reactive,则生效 - ❌ 无效:
Array.from(mySet)[0] = {...}或mySet[0] = ...—— Set 不支持索引赋值
深层响应与只读控制要搭配使用
Map/Set 内部的值(如对象、嵌套 Map)默认不会被自动递归转为响应式——reactive() 只代理集合本身,不自动 deep-reactive 其内容。若需深层响应,应确保插入前已用 reactive() 或 ref() 包裹;若想禁止修改结构,可用 readonly() 包裹整个集合。
- ✅ 深层响应:
myMap.set('user', reactive({ profile: { age: 25 } })) - ✅ 只读保护:
const roMap = readonly(reactive(new Map()))→ 所有修改方法抛错 - ⚠️ 注意:
readonly()不影响内部值的响应性,只拦截集合自身操作

















