fix(reactivity): Array methods relying on identity should work with raw values
This commit is contained in:
parent
3919c7840d
commit
aefb7d282e
@ -44,6 +44,27 @@ describe('reactivity/reactive', () => {
|
||||
expect(clone[0]).toBe(observed[0])
|
||||
})
|
||||
|
||||
test('Array identity methods should work with raw values', () => {
|
||||
const raw = {}
|
||||
const arr = reactive([{}, {}])
|
||||
arr.push(raw)
|
||||
expect(arr.indexOf(raw)).toBe(2)
|
||||
expect(arr.indexOf(raw, 3)).toBe(-1)
|
||||
expect(arr.includes(raw)).toBe(true)
|
||||
expect(arr.includes(raw, 3)).toBe(false)
|
||||
expect(arr.lastIndexOf(raw)).toBe(2)
|
||||
expect(arr.lastIndexOf(raw, 1)).toBe(-1)
|
||||
|
||||
// should work also for the observed version
|
||||
const observed = arr[2]
|
||||
expect(arr.indexOf(observed)).toBe(2)
|
||||
expect(arr.indexOf(observed, 3)).toBe(-1)
|
||||
expect(arr.includes(observed)).toBe(true)
|
||||
expect(arr.includes(observed, 3)).toBe(false)
|
||||
expect(arr.lastIndexOf(observed)).toBe(2)
|
||||
expect(arr.lastIndexOf(observed, 1)).toBe(-1)
|
||||
})
|
||||
|
||||
test('nested reactives', () => {
|
||||
const original = {
|
||||
nested: {
|
||||
|
@ -2,7 +2,7 @@ import { reactive, readonly, toRaw } from './reactive'
|
||||
import { TrackOpTypes, TriggerOpTypes } from './operations'
|
||||
import { track, trigger, ITERATE_KEY } from './effect'
|
||||
import { LOCKED } from './lock'
|
||||
import { isObject, hasOwn, isSymbol, hasChanged } from '@vue/shared'
|
||||
import { isObject, hasOwn, isSymbol, hasChanged, isArray } from '@vue/shared'
|
||||
import { isRef } from './ref'
|
||||
|
||||
const builtInSymbols = new Set(
|
||||
@ -15,8 +15,21 @@ const get = /*#__PURE__*/ createGetter()
|
||||
const readonlyGet = /*#__PURE__*/ createGetter(true)
|
||||
const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true)
|
||||
|
||||
const arrayIdentityInstrumentations: Record<string, Function> = {}
|
||||
;['includes', 'indexOf', 'lastIndexOf'].forEach(key => {
|
||||
arrayIdentityInstrumentations[key] = function(
|
||||
value: unknown,
|
||||
...args: any[]
|
||||
): any {
|
||||
return toRaw(this)[key](toRaw(value), ...args)
|
||||
}
|
||||
})
|
||||
|
||||
function createGetter(isReadonly = false, shallow = false) {
|
||||
return function get(target: object, key: string | symbol, receiver: object) {
|
||||
if (isArray(target) && hasOwn(arrayIdentityInstrumentations, key)) {
|
||||
return Reflect.get(arrayIdentityInstrumentations, key, receiver)
|
||||
}
|
||||
const res = Reflect.get(target, key, receiver)
|
||||
if (isSymbol(key) && builtInSymbols.has(key)) {
|
||||
return res
|
||||
|
Loading…
Reference in New Issue
Block a user