Răsfoiți Sursa

refactor(runtime-core): make setup attrs proxy dev only

Evan You 6 ani în urmă
părinte
comite
c5f0f63b91

+ 14 - 1
packages/runtime-core/src/component.ts

@@ -504,12 +504,25 @@ const SetupProxyHandlers: { [key: string]: ProxyHandler<any> } = {}
   }
 })
 
+const attrsProxyHandlers: ProxyHandler<Data> = {
+  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

+ 3 - 2
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

+ 5 - 2
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<P = Data> =
   | ComponentObjectPropsOptions<P>
@@ -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
 }
 

+ 3 - 2
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

+ 5 - 1
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 })
+}