diff --git a/packages/reactivity/__tests__/readonly.spec.ts b/packages/reactivity/__tests__/readonly.spec.ts index 63426bb5e9c..185bb310759 100644 --- a/packages/reactivity/__tests__/readonly.spec.ts +++ b/packages/reactivity/__tests__/readonly.spec.ts @@ -465,4 +465,13 @@ describe('reactivity/readonly', () => { 'Set operation on key "randomProperty" failed: target is readonly.' ).toHaveBeenWarned() }) + + // #4986 + test('setting a readonly object as a property of a reactive object should retain readonly proxy', () => { + const r = readonly({}) + const rr = reactive({}) as any + rr.foo = r + expect(rr.foo).toBe(r) + expect(isReadonly(rr.foo)).toBe(true) + }) }) diff --git a/packages/reactivity/src/baseHandlers.ts b/packages/reactivity/src/baseHandlers.ts index 29367007c13..0fa1c4bc2ea 100644 --- a/packages/reactivity/src/baseHandlers.ts +++ b/packages/reactivity/src/baseHandlers.ts @@ -7,7 +7,8 @@ import { readonlyMap, reactiveMap, shallowReactiveMap, - shallowReadonlyMap + shallowReadonlyMap, + isReadonly } from './reactive' import { TrackOpTypes, TriggerOpTypes } from './operations' import { @@ -146,7 +147,7 @@ function createSetter(shallow = false) { receiver: object ): boolean { let oldValue = (target as any)[key] - if (!shallow) { + if (!shallow && !isReadonly(value)) { value = toRaw(value) oldValue = toRaw(oldValue) if (!isArray(target) && isRef(oldValue) && !isRef(value)) {