From: ᴜɴвʏтᴇ Date: Fri, 21 Aug 2020 17:36:41 +0000 (+0800) Subject: fix(reactivity): unwrap non-index accessed refs on reactive arrays (#1859) X-Git-Tag: v3.0.0-rc.7~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3c05f8bbd6cd0e01bbc5830730852f9a93d8de8a;p=thirdparty%2Fvuejs%2Fcore.git fix(reactivity): unwrap non-index accessed refs on reactive arrays (#1859) close #1846 --- diff --git a/packages/reactivity/__tests__/ref.spec.ts b/packages/reactivity/__tests__/ref.spec.ts index bae4ec35a3..9ef6c4e4b1 100644 --- a/packages/reactivity/__tests__/ref.spec.ts +++ b/packages/reactivity/__tests__/ref.spec.ts @@ -115,6 +115,19 @@ describe('reactivity/ref', () => { expect((arr[1] as Ref).value).toBe(3) }) + it('should unwrap ref types as props of arrays', () => { + const arr = [ref(0)] + const symbolKey = Symbol('') + arr['' as any] = ref(1) + arr[symbolKey as any] = ref(2) + const arrRef = ref(arr).value + expect(isRef(arrRef[0])).toBe(true) + expect(isRef(arrRef['' as any])).toBe(false) + expect(isRef(arrRef[symbolKey as any])).toBe(false) + expect(arrRef['' as any]).toBe(1) + expect(arrRef[symbolKey as any]).toBe(2) + }) + it('should keep tuple types', () => { const tuple: [number, string, { a: number }, () => number, Ref] = [ 0, diff --git a/packages/reactivity/src/baseHandlers.ts b/packages/reactivity/src/baseHandlers.ts index 11a7b1cc04..8d8112e926 100644 --- a/packages/reactivity/src/baseHandlers.ts +++ b/packages/reactivity/src/baseHandlers.ts @@ -63,9 +63,10 @@ function createGetter(isReadonly = false, shallow = false) { const res = Reflect.get(target, key, receiver) + const keyIsSymbol = isSymbol(key) if ( - isSymbol(key) - ? builtInSymbols.has(key) + keyIsSymbol + ? builtInSymbols.has(key as symbol) : key === `__proto__` || key === `__v_isRef` ) { return res @@ -80,8 +81,12 @@ function createGetter(isReadonly = false, shallow = false) { } if (isRef(res)) { - // ref unwrapping, only for Objects, not for Arrays. - return targetIsArray ? res : res.value + // ref unwrapping - does not apply for Array + integer key. + const shouldUnwrap = + !targetIsArray || + keyIsSymbol || + '' + parseInt(key as string, 10) !== key + return shouldUnwrap ? res.value : res } if (isObject(res)) {