Browse Source

feat(computed): add readonly flag if no setter is provided (#1654)

Carlos Rodrigues 5 years ago
parent
commit
dabdc5e115

+ 20 - 1
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<typeof a>({
+      get() {
+        return a
+      },
+      set(v) {
+        a = v
+      }
+    })
+    expect(isReadonly(z)).toBe(false)
+    expect(isReadonly(z.value.a)).toBe(false)
+  })
 })

+ 4 - 0
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<T = any> extends WritableComputedRef<T> {
   readonly value: T
@@ -56,6 +57,9 @@ export function computed<T>(
   })
   computed = {
     __v_isRef: true,
+    [ReactiveFlags.IS_READONLY]:
+      isFunction(getterOrOptions) || !getterOrOptions.set,
+
     // expose effect so computed can be stopped
     effect: runner,
     get value() {