diff --git a/packages/reactivity/__tests__/computed.spec.ts b/packages/reactivity/__tests__/computed.spec.ts index 5ab4641e..fe6161ff 100644 --- a/packages/reactivity/__tests__/computed.spec.ts +++ b/packages/reactivity/__tests__/computed.spec.ts @@ -4,7 +4,8 @@ import { effect, stop, ref, - WritableComputedRef + WritableComputedRef, + isReadonly } from '../src' import { mockWarn } from '@vue/shared' @@ -177,4 +178,22 @@ describe('reactivity/computed', () => { 'Write operation failed: computed value is readonly' ).toHaveBeenWarnedLast() }) + + it('should be readonly', () => { + let a = { a: 1 } + const x = computed(() => a) + expect(isReadonly(x)).toBe(true) + expect(isReadonly(x.value)).toBe(false) + expect(isReadonly(x.value.a)).toBe(false) + const z = computed({ + get() { + return a + }, + set(v) { + a = v + } + }) + expect(isReadonly(z)).toBe(false) + expect(isReadonly(z.value.a)).toBe(false) + }) }) diff --git a/packages/reactivity/src/computed.ts b/packages/reactivity/src/computed.ts index 9aa7c6cf..32740f98 100644 --- a/packages/reactivity/src/computed.ts +++ b/packages/reactivity/src/computed.ts @@ -2,6 +2,7 @@ import { effect, ReactiveEffect, trigger, track } from './effect' import { TriggerOpTypes, TrackOpTypes } from './operations' import { Ref } from './ref' import { isFunction, NOOP } from '@vue/shared' +import { ReactiveFlags } from './reactive' export interface ComputedRef extends WritableComputedRef { readonly value: T @@ -56,6 +57,9 @@ export function computed( }) computed = { __v_isRef: true, + [ReactiveFlags.IS_READONLY]: + isFunction(getterOrOptions) || !getterOrOptions.set, + // expose effect so computed can be stopped effect: runner, get value() {