From ea3ad5ca810ceb75360ab55aaca06749746f5d95 Mon Sep 17 00:00:00 2001 From: ygj6 Date: Thu, 27 May 2021 15:07:18 +0800 Subject: [PATCH] fix(shallowReadonly) : shallowReadonly should work for ref. (#704) --- src/reactivity/readonly.ts | 8 ++++++-- test/v3/reactivity/readonly.spec.ts | 31 ++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/reactivity/readonly.ts b/src/reactivity/readonly.ts index c4e34459..dc4bcbd0 100644 --- a/src/reactivity/readonly.ts +++ b/src/reactivity/readonly.ts @@ -1,6 +1,7 @@ import { reactive, Ref, UnwrapRef } from '.' import { isArray, isPlainObject, warn } from '../utils' import { readonlySet } from '../utils/sets' +import { isRef } from './ref' export function isReadonly(obj: any): boolean { return readonlySet.has(obj) @@ -47,7 +48,10 @@ export function readonly( export function shallowReadonly(obj: T): Readonly export function shallowReadonly(obj: any): any { - if (!(isPlainObject(obj) || isArray(obj)) || !Object.isExtensible(obj)) { + if ( + !(isPlainObject(obj) || isArray(obj)) || + (!Object.isExtensible(obj) && !isRef(obj)) + ) { return obj } @@ -60,7 +64,7 @@ export function shallowReadonly(obj: any): any { let val = obj[key] let getter: (() => any) | undefined const property = Object.getOwnPropertyDescriptor(obj, key) - if (property) { + if (property && !isRef(obj)) { if (property.configurable === false) { continue } diff --git a/test/v3/reactivity/readonly.spec.ts b/test/v3/reactivity/readonly.spec.ts index b6cc56d7..55131305 100644 --- a/test/v3/reactivity/readonly.spec.ts +++ b/test/v3/reactivity/readonly.spec.ts @@ -1,5 +1,7 @@ import { mockWarn } from '../../helpers/mockWarn' -import { shallowReadonly, isReactive } from '../../../src' +import { shallowReadonly, isReactive, ref, reactive } from '../../../src' + +const Vue = require('vue/dist/vue.common.js') // /** // * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html @@ -372,5 +374,32 @@ describe('reactivity/readonly', () => { `Set operation on key "foo" failed: target is readonly.` ).not.toHaveBeenWarned() }) + + // #669 + test('shallowReadonly should work for refs', () => { + const vm = new Vue({ + template: '
{{ count }} {{ countRef }}
', + setup() { + const count = reactive({ number: 0 }) + const countRef = ref(0) + + const countReadonly = shallowReadonly(count) + const countRefReadonly = shallowReadonly(countRef) + + setTimeout(() => { + // @ts-expect-error + countReadonly.number++ + // @ts-expect-error + countRefReadonly.value++ + }, 2000) + return { + count, + countRef, + } + }, + }).$mount() + + expect(vm.$el.textContent).toBe(`{\n "number": 0\n} 0`) + }) }) })