与 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']
这几个方法