From: Thorsten Lünborg Date: Sun, 23 Jan 2022 13:08:27 +0000 (+0100) Subject: fix(reactivity): ensure readonly refs can be replaced with new refs in reactive objec... X-Git-Tag: v3.2.29~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4be1037f31e169d667059c44364fc3e43803accb;p=thirdparty%2Fvuejs%2Fcore.git fix(reactivity): ensure readonly refs can be replaced with new refs in reactive objects (#5310) fix #5307 --- diff --git a/packages/reactivity/__tests__/readonly.spec.ts b/packages/reactivity/__tests__/readonly.spec.ts index 4462061b3a..73030c5b99 100644 --- a/packages/reactivity/__tests__/readonly.spec.ts +++ b/packages/reactivity/__tests__/readonly.spec.ts @@ -476,7 +476,7 @@ describe('reactivity/readonly', () => { expect(isReadonly(rr.foo)).toBe(true) }) - test('attemptingt to write to a readonly ref nested in a reactive object should fail', () => { + test('attemptingt to write plain value to a readonly ref nested in a reactive object should fail', () => { const r = ref(false) const ror = readonly(r) const obj = reactive({ ror }) @@ -486,4 +486,15 @@ describe('reactivity/readonly', () => { expect(obj.ror).toBe(false) }) + test('replacing a readonly ref nested in a reactive object with a new ref', () => { + const r = ref(false) + const ror = readonly(r) + const obj = reactive({ ror }) + try { + obj.ror = ref(true) as unknown as boolean + } catch (e) {} + + expect(obj.ror).toBe(true) + expect(toRaw(obj).ror).not.toBe(ror) // ref successfully replaced + }) }) diff --git a/packages/reactivity/src/baseHandlers.ts b/packages/reactivity/src/baseHandlers.ts index eed9dc8509..8ad8e57171 100644 --- a/packages/reactivity/src/baseHandlers.ts +++ b/packages/reactivity/src/baseHandlers.ts @@ -150,7 +150,7 @@ function createSetter(shallow = false) { receiver: object ): boolean { let oldValue = (target as any)[key] - if (isReadonly(oldValue) && isRef(oldValue)) { + if (isReadonly(oldValue) && isRef(oldValue) && !isRef(value)) { return false } if (!shallow && !isReadonly(value)) {