vue2 使用 Object.defineProperty 不同, vue3 主要使用 Proxy 处理响应性,进而进行依赖跟踪和变更通知。

来看下 vue3的reactive 直接对数组赋值的操作


const ary = reactive([]); // 注意:ary是一个Proxy对象

ary = [1, 2, 3] // 失败,直接赋值会丢失响应性

所以在 vue3 中我们对数组和对象 整个 进行赋值不起作用

那么可以采用以下几种方式声明和处理数组:


const ary = ref([]);

ary.value = [1, 2, 3] 


const ary = reactive([]);

ary.push(...[1, 2, 3])

或者
ary[0] = 1
ary[1] = 2
ary[2] = 3

或者
ary.splice.apply(ary, [0, ary.length, ...[1, 2, 3]])
const obj = reactive({
 ary: []
})

obj.ary = [1, 2, 3];

以下为vue-next 源码部分截图


packages/reactivity/src/baseHandlers.ts


// instrument length-altering mutation methods to avoid length being tracked
// which leads to infinite loops in some cases (#2137)
;(['push', 'pop', 'shift', 'unshift', 'splice'] as const).forEach(key => {
  const method = Array.prototype[key] as any
  arrayInstrumentations[key] = function(this: unknown[], ...args: unknown[]) {
    pauseTracking()
    const res = method.apply(this, args)
    resetTracking()
    return res
  }
})


const targetIsArray = isArray(target)

if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
  return Reflect.get(arrayInstrumentations, key, receiver)
}

另外 reactive 也支持数组的 ['includes', 'indexOf', 'lastIndexOf'] 这几个方法


最后修改:2023 年 10 月 09 日
如果觉得我的文章对你有用,请随意赞赏或留下你的评论~