Vue 3 数组(Array)、集合(Set) 和 映射(Map) 详解

一、数组(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. 最佳实践
  • 优先使用 push/pop/splice 等原生方法
  • 需要整体替换时:
    // reactive 方式
    arrReactive.splice(0, arrReactive.length, ...newArray)
    
    // ref 方式
    arrRef.value = newArray
    

二、集合(Set)

1. 响应式创建
const setReactive = reactive(new Set([1, 2, 3]))
 
  • 自动追踪的操作
    setReactive.add(4)         // 触发更新
    setReactive.delete(2)      // 触发更新
    setReactive.clear()        // 触发更新
    
  • 注意事项
    • 直接修改元素不会触发更新(必须通过 Set 方法)
    • 存储对象时需保持响应式:
      const obj = reactive({ id: 1 })
      setReactive.add(obj)     // 对象修改会触发更新
      
      

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. 响应式特性
  • 自动追踪的操作
    mapReactive.set('key2', 'value2')  // 触发更新
    mapReactive.delete('key1')         // 触发更新
    mapReactive.clear()                // 触发更新
    

  • 键值处理
    • 键可以是任意类型(包括对象)
    • 值若为对象需保持响应式:
      mapReactive.set('user', reactive({ name: 'Alice' }))
      

3. 模板使用
<template>
  <div v-for="[key, value] in mapReactive" :key="key">
    {{ key }}: {{ value }}
  </div>
</template>

四、三者对比

特性数组 (Array)集合 (Set)映射 (Map)
数据结构有序索引集合唯一值集合键值对集合
响应式触发方式索引修改/原生方法add/delete/clearset/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. 性能优化
  • 对超大数据集使用 shallowRef
    const bigData = shallowRef(new Array(100000).fill(0))
    // 手动触发更新
    bigData.value = [...bigData.value]
    


六、常见问题

1. 为什么修改 Set/Map 的元素不触发更新?
  • 根本原因:Proxy 只跟踪集合的整体操作(如 add/delete),不追踪元素内部变化
  • 解决方案
    // 对于对象元素
    const obj = reactive({ data: 1 })
    setReactive.add(obj)
    
    // 修改时会触发更新(因为 obj 是响应式的)
    obj.data = 2
    

2. 如何强制更新集合?
// 通过重新赋值触发更新
setReactive = new Set([...setReactive, newItem])

// 或使用 ref + spread
const setRef = ref(new Set())
setRef.value = new Set([...setRef.value, newItem])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值