'Vapor component setup() returned non-block value, and has no render function',
).toHaveBeenWarned()
})
+
+ it('warn non-existent property access', () => {
+ define({
+ setup() {
+ return {}
+ },
+ render(ctx: any) {
+ ctx.foo
+ return []
+ },
+ }).render()
+
+ expect(
+ 'Property "foo" was accessed during render but is not defined on instance.',
+ ).toHaveBeenWarned()
+ })
})
function getEffectsCount(scope: EffectScope): number {
onScopeDispose,
proxyRefs,
setActiveSub,
+ toRaw,
unref,
} from '@vue/reactivity'
import {
EMPTY_OBJ,
ShapeFlags,
+ hasOwn,
invokeArrayFns,
isArray,
isFunction,
)
instance.block = []
} else {
- instance.devtoolsRawSetupState = setupResult
- // TODO make the proxy warn non-existent property access during dev
instance.setupState = proxyRefs(setupResult)
+ if (__DEV__) {
+ instance.setupState = createDevSetupStateProxy(instance)
+ }
devRender(instance)
}
} else {
isApplyingFallthroughProps = false
}
+/**
+ * dev only
+ */
+function createDevSetupStateProxy(
+ instance: VaporComponentInstance,
+): Record<string, any> {
+ const { setupState } = instance
+ return new Proxy(setupState!, {
+ get(target, key: string | symbol, receiver) {
+ if (
+ isString(key) &&
+ !key.startsWith('__v') &&
+ !hasOwn(toRaw(setupState)!, key)
+ ) {
+ warn(
+ `Property ${JSON.stringify(key)} was accessed during render ` +
+ `but is not defined on instance.`,
+ )
+ }
+
+ return Reflect.get(target, key, receiver)
+ },
+ })
+}
+
/**
* dev only
*/