From c5f0f63b914e3a30e05694547e3789837471c893 Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 6 Apr 2020 17:57:27 -0400 Subject: [PATCH] refactor(runtime-core): make setup attrs proxy dev only --- packages/runtime-core/src/component.ts | 15 ++++++++++++++- packages/runtime-core/src/componentEmits.ts | 5 +++-- packages/runtime-core/src/componentProps.ts | 7 +++++-- packages/runtime-core/src/vnode.ts | 5 +++-- packages/shared/src/index.ts | 6 +++++- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index 96fe688488..f05fdde851 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -504,12 +504,25 @@ const SetupProxyHandlers: { [key: string]: ProxyHandler } = {} } }) +const attrsProxyHandlers: ProxyHandler = { + get(target, key: string) { + if (__DEV__) { + markAttrsAccessed() + } + return target[key] + }, + set: () => false, + deleteProperty: () => false +} + function createSetupContext(instance: ComponentInternalInstance): SetupContext { const context = { // attrs & slots are non-reactive, but they need to always expose // the latest values (instance.xxx may get replaced during updates) so we // need to expose them through a proxy - attrs: new Proxy(instance, SetupProxyHandlers.attrs), + attrs: __DEV__ + ? new Proxy(instance.attrs, attrsProxyHandlers) + : instance.attrs, slots: new Proxy(instance, SetupProxyHandlers.slots), get emit() { return instance.emit diff --git a/packages/runtime-core/src/componentEmits.ts b/packages/runtime-core/src/componentEmits.ts index 78a78ef51d..7ece305c04 100644 --- a/packages/runtime-core/src/componentEmits.ts +++ b/packages/runtime-core/src/componentEmits.ts @@ -5,7 +5,8 @@ import { EMPTY_OBJ, capitalize, hyphenate, - isFunction + isFunction, + def } from '@vue/shared' import { ComponentInternalInstance } from './component' import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling' @@ -96,7 +97,7 @@ export function normalizeEmitsOptions( } const normalized: ObjectEmitsOptions = {} options.forEach(key => (normalized[key] = null)) - Object.defineProperty(options, '_n', { value: normalized }) + def(options, '_n', normalized) return normalized } else { return options diff --git a/packages/runtime-core/src/componentProps.ts b/packages/runtime-core/src/componentProps.ts index a4dcf1cb17..2ceb9aa977 100644 --- a/packages/runtime-core/src/componentProps.ts +++ b/packages/runtime-core/src/componentProps.ts @@ -13,11 +13,13 @@ import { PatchFlags, makeMap, isReservedProp, - EMPTY_ARR + EMPTY_ARR, + def } from '@vue/shared' import { warn } from './warning' import { Data, ComponentInternalInstance } from './component' import { isEmitListener } from './componentEmits' +import { InternalObjectSymbol } from './vnode' export type ComponentPropsOptions

= | ComponentObjectPropsOptions

@@ -102,6 +104,7 @@ export function initProps( ) { const props: Data = {} const attrs: Data = {} + def(attrs, InternalObjectSymbol, true) setFullProps(instance, rawProps, props, attrs) const options = instance.type.props // validation @@ -310,7 +313,7 @@ export function normalizePropsOptions( } } const normalizedEntry: NormalizedPropsOptions = [normalized, needCastKeys] - Object.defineProperty(raw, '_n', { value: normalizedEntry }) + def(raw, '_n', normalizedEntry) return normalizedEntry } diff --git a/packages/runtime-core/src/vnode.ts b/packages/runtime-core/src/vnode.ts index a43ab687eb..8764808a3f 100644 --- a/packages/runtime-core/src/vnode.ts +++ b/packages/runtime-core/src/vnode.ts @@ -13,7 +13,6 @@ import { import { ComponentInternalInstance, Data, - SetupProxySymbol, Component, ClassComponent } from './component' @@ -235,6 +234,8 @@ const createVNodeWithArgsTransform = ( ) } +export const InternalObjectSymbol = Symbol() + export const createVNode = (__DEV__ ? createVNodeWithArgsTransform : _createVNode) as typeof _createVNode @@ -261,7 +262,7 @@ function _createVNode( // class & style normalization. if (props) { // for reactive or proxy objects, we need to clone it to enable mutation. - if (isReactive(props) || SetupProxySymbol in props) { + if (isReactive(props) || InternalObjectSymbol in props) { props = extend({}, props) } let { class: klass, style } = props diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 75c6f0fbd6..fd4e149d52 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -120,8 +120,12 @@ export const toDisplayString = (val: unknown): string => { : String(val) } -export function invokeArrayFns(fns: Function[], arg?: any) { +export const invokeArrayFns = (fns: Function[], arg?: any) => { for (let i = 0; i < fns.length; i++) { fns[i](arg) } } + +export const def = (obj: object, key: string | symbol, value: any) => { + Object.defineProperty(obj, key, { value }) +} -- 2.47.2