Browse Source

feat(apiOptions): warn invalid computed options (#225)

Cr 6 năm trước cách đây
mục cha
commit
d2bcedb213

+ 37 - 0
packages/runtime-core/__tests__/apiOptions.spec.ts

@@ -538,5 +538,42 @@ describe('api: options', () => {
 
       expect('Invalid watch option: "foo"').toHaveBeenWarned()
     })
+
+    test('computed with setter and no getter', () => {
+      const Comp = {
+        computed: {
+          foo: {
+            set() {}
+          }
+        },
+        render() {}
+      }
+
+      const root = nodeOps.createElement('div')
+      render(h(Comp), root)
+      expect('Computed property "foo" has no getter.').toHaveBeenWarned()
+    })
+
+    test('assigning to computed with no setter', () => {
+      let instance: any
+      const Comp = {
+        computed: {
+          foo: {
+            get() {}
+          }
+        },
+        mounted() {
+          instance = this
+        },
+        render() {}
+      }
+
+      const root = nodeOps.createElement('div')
+      render(h(Comp), root)
+      instance.foo = 1
+      expect(
+        'Computed property "foo" was assigned to but it has no setter.'
+      ).toHaveBeenWarned()
+    })
   })
 })

+ 23 - 6
packages/runtime-core/src/apiOptions.ts

@@ -10,7 +10,8 @@ import {
   isString,
   isObject,
   isArray,
-  EMPTY_OBJ
+  EMPTY_OBJ,
+  NOOP
 } from '@vue/shared'
 import { computed } from './apiReactivity'
 import { watch, WatchOptions, CleanupRegistrator } from './apiWatch'
@@ -245,12 +246,28 @@ export function applyOptions(
   if (computedOptions) {
     for (const key in computedOptions) {
       const opt = (computedOptions as ComputedOptions)[key]
-      renderContext[key] = isFunction(opt)
-        ? computed(opt.bind(ctx))
-        : computed({
-            get: opt.get.bind(ctx),
-            set: opt.set.bind(ctx)
+
+      if (isFunction(opt)) {
+        renderContext[key] = computed(opt.bind(ctx))
+      } else {
+        const { get, set } = opt
+        if (isFunction(get)) {
+          renderContext[key] = computed({
+            get: get.bind(ctx),
+            set: isFunction(set)
+              ? set.bind(ctx)
+              : __DEV__
+                ? () => {
+                    warn(
+                      `Computed property "${key}" was assigned to but it has no setter.`
+                    )
+                  }
+                : NOOP
           })
+        } else if (__DEV__) {
+          warn(`Computed property "${key}" has no getter.`)
+        }
+      }
     }
   }
   if (methods) {