From 2d04337c723267ada382ec38b3999dd24a027868 Mon Sep 17 00:00:00 2001 From: Helios Date: Sat, 15 Aug 2020 01:32:51 +0800 Subject: [PATCH 1/4] fix(reactivity): unwrap ref types as props of arrays close #1846 --- packages/reactivity/__tests__/ref.spec.ts | 9 +++++++++ packages/reactivity/src/baseHandlers.ts | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/reactivity/__tests__/ref.spec.ts b/packages/reactivity/__tests__/ref.spec.ts index 6bfcceaef54..4733291c1e4 100644 --- a/packages/reactivity/__tests__/ref.spec.ts +++ b/packages/reactivity/__tests__/ref.spec.ts @@ -115,6 +115,15 @@ describe('reactivity/ref', () => { expect((arr[1] as Ref).value).toBe(3) }) + it('should unwrap ref types as props of arrays', () => { + const arr = [ref(0)] + arr['' as any] = ref(1) + const arrRef = ref(arr).value + expect(isRef(arrRef[0])).toBe(true) + expect(isRef(arrRef['' as any])).toBe(false) + expect(arrRef['' as any]).toBe(1) + }) + 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 6c0a1a4464e..8f921a0f37d 100644 --- a/packages/reactivity/src/baseHandlers.ts +++ b/packages/reactivity/src/baseHandlers.ts @@ -81,7 +81,10 @@ function createGetter(isReadonly = false, shallow = false) { if (isRef(res)) { // ref unwrapping, only for Objects, not for Arrays. - return targetIsArray ? res : res.value + const shouldUnwrap = + !targetIsArray || isNaN(key as any) || isSymbol(key) || key === '' + + return shouldUnwrap ? res.value : res } if (isObject(res)) { From 6742186b10be51e8e0e00bda2e13a946b2c6365e Mon Sep 17 00:00:00 2001 From: Helios Date: Sat, 15 Aug 2020 10:28:22 +0800 Subject: [PATCH 2/4] fix(reactivity): check isSymbol before isNaN --- packages/reactivity/__tests__/ref.spec.ts | 4 ++++ packages/reactivity/src/baseHandlers.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/reactivity/__tests__/ref.spec.ts b/packages/reactivity/__tests__/ref.spec.ts index 4733291c1e4..c129da557aa 100644 --- a/packages/reactivity/__tests__/ref.spec.ts +++ b/packages/reactivity/__tests__/ref.spec.ts @@ -117,11 +117,15 @@ describe('reactivity/ref', () => { 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', () => { diff --git a/packages/reactivity/src/baseHandlers.ts b/packages/reactivity/src/baseHandlers.ts index 8f921a0f37d..f8f1cbc7776 100644 --- a/packages/reactivity/src/baseHandlers.ts +++ b/packages/reactivity/src/baseHandlers.ts @@ -82,7 +82,7 @@ function createGetter(isReadonly = false, shallow = false) { if (isRef(res)) { // ref unwrapping, only for Objects, not for Arrays. const shouldUnwrap = - !targetIsArray || isNaN(key as any) || isSymbol(key) || key === '' + !targetIsArray || isSymbol(key) || isNaN(key as any) || key === '' return shouldUnwrap ? res.value : res } From 5112eb7d6cd618a176621c3ecb8347c6a27b63ca Mon Sep 17 00:00:00 2001 From: Helios Date: Thu, 20 Aug 2020 08:56:51 +0800 Subject: [PATCH 3/4] fix(reactivity): cover edge cases of properties of array --- packages/reactivity/src/baseHandlers.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/reactivity/src/baseHandlers.ts b/packages/reactivity/src/baseHandlers.ts index f8f1cbc7776..c59c331d764 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 @@ -82,7 +83,9 @@ function createGetter(isReadonly = false, shallow = false) { if (isRef(res)) { // ref unwrapping, only for Objects, not for Arrays. const shouldUnwrap = - !targetIsArray || isSymbol(key) || isNaN(key as any) || key === '' + !targetIsArray || + keyIsSymbol || + '' + parseInt(key as string, 10) !== key return shouldUnwrap ? res.value : res } From 709e0bdafcc8ef424c8ef21a40350eccfb768989 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 21 Aug 2020 13:05:33 -0400 Subject: [PATCH 4/4] Update baseHandlers.ts --- packages/reactivity/src/baseHandlers.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/reactivity/src/baseHandlers.ts b/packages/reactivity/src/baseHandlers.ts index c59c331d764..a5fd84630d3 100644 --- a/packages/reactivity/src/baseHandlers.ts +++ b/packages/reactivity/src/baseHandlers.ts @@ -81,12 +81,11 @@ function createGetter(isReadonly = false, shallow = false) { } if (isRef(res)) { - // ref unwrapping, only for Objects, not for Arrays. + // ref unwrapping - does not apply for Array + integer key. const shouldUnwrap = !targetIsArray || keyIsSymbol || '' + parseInt(key as string, 10) !== key - return shouldUnwrap ? res.value : res }