From 8c1638da33036fc2b2b5fa363fd89e54ce471670 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 25 Oct 2019 10:12:43 -0400 Subject: [PATCH] feat(runtime-core): warn access of undefined property during render --- packages/runtime-core/src/componentProxy.ts | 24 +++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/packages/runtime-core/src/componentProxy.ts b/packages/runtime-core/src/componentProxy.ts index b54f927a..cf8448cb 100644 --- a/packages/runtime-core/src/componentProxy.ts +++ b/packages/runtime-core/src/componentProxy.ts @@ -11,6 +11,7 @@ import { import { UnwrapRef, ReactiveEffect } from '@vue/reactivity' import { warn } from './warning' import { Slots } from './componentSlots' +import { currentRenderingInstance } from './componentRenderUtils' // public properties exposed on the proxy, which is used as the render context // in templates (as `this` in the render option) @@ -62,7 +63,19 @@ const enum AccessTypes { export const PublicInstanceProxyHandlers: ProxyHandler = { get(target: ComponentInternalInstance, key: string) { - const { renderContext, data, props, propsProxy, accessCache, type } = target + const { + renderContext, + data, + props, + propsProxy, + accessCache, + type, + user + } = target + // fast path for unscopables when using `with` block + if (__RUNTIME_COMPILE__ && (key as any) === Symbol.unscopables) { + return + } // This getter gets called for every property access on the render context // during render and is a major hotspot. The most expensive part of this // is the multiple hasOwn() calls. It's much faster to do a simple property @@ -109,7 +122,14 @@ export const PublicInstanceProxyHandlers: ProxyHandler = { return instanceWatch.bind(target) } } - return target.user[key] + if (hasOwn(user, key)) { + return user[key] + } else if (__DEV__ && currentRenderingInstance != null) { + warn( + `Property ${JSON.stringify(key)} was accessed during render ` + + `but is not defined on instance.` + ) + } }, set(target: ComponentInternalInstance, key: string, value: any): boolean {