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

This commit is contained in:
Cr 2019-10-14 14:15:31 +08:00 committed by Evan You
parent 82b5978e9c
commit d2bcedb213
2 changed files with 60 additions and 6 deletions

View File

@ -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()
})
})
})

View File

@ -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) {