一、数组(Array)
1. 响应式创建
import { reactive, ref } from 'vue'
// 方式1:使用 reactive(推荐对象型数组)
const arrReactive = reactive([1, 2, 3])
// 方式2:使用 ref(适合基本类型数组)
const arrRef = ref([1, 2, 3])
2. 响应式特性
- 自动追踪的操作:
arrReactive.push(4) // 触发更新
arrReactive.splice(0, 1) // 触发更新
arrReactive[0] = 100 // 触发更新(Vue 3 特有,Vue 2 不支援)
arrReactive.length = 0 // 触发更新
- 非响应式场景:
// 直接设置超出当前长度的索引
arrReactive[10] = 10 // 不触发更新(需先用其他方法扩展数组)
3. 模板使用
<template>
<div v-for="(item, index) in arrReactive" :key="index">
{{ item }}
</div>
</template>
4. 最佳实践
二、集合(Set)
1. 响应式创建
const setReactive = reactive(new Set([1, 2, 3]))
3. 模板使用
<template>
<div v-for="item in setReactive" :key="item">
{{ item }}
</div>
</template>
4. 工具方法
// 转换为响应式数组
const arrFromSet = reactive(Array.from(setReactive))
// 检查存在性
const hasItem = computed(() => setReactive.has(2))
三、映射(Map)
1. 响应式创建
const mapReactive = reactive(new Map([['key1', 'value1']]))
2. 响应式特性
3. 模板使用
<template>
<div v-for="[key, value] in mapReactive" :key="key">
{{ key }}: {{ value }}
</div>
</template>
四、三者对比
特性 | 数组 (Array) | 集合 (Set) | 映射 (Map) |
---|
数据结构 | 有序索引集合 | 唯一值集合 | 键值对集合 |
响应式触发方式 | 索引修改/原生方法 | add/delete/clear | set/delete/clear |
查找效率 | O(n) | O(1)(哈希表) | O(1)(键查找) |
典型场景 | 有序列表、简单数据集合 | 去重、存在性检查 | 键值关联、复杂键需求 |
内存占用 | 较低 | 较高(维护哈希表) | 较高(存储键值对) |
五、高级技巧
1. 浅层响应式
import { shallowReactive, shallowRef } from 'vue'
// 仅跟踪顶层变化
const shallowArr = shallowReactive([{ id: 1 }])
shallowArr.push({ id: 2 }) // 触发更新
shallowArr[0].id = 2 // 不触发更新
const shallowSet = shallowReactive(new Set())
2. 响应式转换
// Set → 响应式数组
const reactiveArray = reactive(Array.from(setReactive))
// Map → 响应式对象
const reactiveObj = reactive(Object.fromEntries(mapReactive))
3. 性能优化
六、常见问题
1. 为什么修改 Set/Map 的元素不触发更新?
2. 如何强制更新集合?
// 通过重新赋值触发更新
setReactive = new Set([...setReactive, newItem])
// 或使用 ref + spread
const setRef = ref(new Set())
setRef.value = new Set([...setRef.value, newItem])