]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: should resolve dynamic props first + optimize ownKeys
authorEvan You <evan@vuejs.org>
Thu, 5 Dec 2024 05:17:28 +0000 (13:17 +0800)
committerEvan You <evan@vuejs.org>
Thu, 5 Dec 2024 05:17:28 +0000 (13:17 +0800)
packages/runtime-vapor/src/componentProps.ts
packages/shared/src/general.ts

index e98418ac10976fcba851543a62d2b57ec5fa2078..922e75a877cf0d0d72ab221c267abe8d910bf7c7 100644 (file)
@@ -1,4 +1,4 @@
-import { EMPTY_ARR, NO, hasOwn, isFunction } from '@vue/shared'
+import { EMPTY_ARR, NO, YES, hasOwn, isFunction } from '@vue/shared'
 import type { VaporComponent, VaporComponentInstance } from './component'
 import {
   type NormalizedPropsOptions,
@@ -35,6 +35,11 @@ export function getPropsProxyHandlers(
   const propsOptions = normalizePropsOptions(comp)[0]
   const emitsOptions = normalizeEmitsOptions(comp)
   const isProp = propsOptions ? (key: string) => hasOwn(propsOptions, key) : NO
+  const isAttr = propsOptions
+    ? (key: string) =>
+        key !== '$' && !isProp(key) && !isEmitListener(emitsOptions, key)
+    : YES
+
   const castProp = propsOptions
     ? (value: any, key: string, isAbsent = false) =>
         resolvePropValue(
@@ -53,10 +58,6 @@ export function getPropsProxyHandlers(
     } else if (isProp(key) || isEmitListener(emitsOptions, key)) {
       return
     }
-
-    if (key in target) {
-      return castProp(target[key as string](), key)
-    }
     const dynamicSources = target.$
     if (dynamicSources) {
       let i = dynamicSources.length
@@ -70,6 +71,9 @@ export function getPropsProxyHandlers(
         }
       }
     }
+    if (key in target) {
+      return castProp(target[key as string](), key)
+    }
     return castProp(undefined, key, true)
   }
 
@@ -93,19 +97,20 @@ export function getPropsProxyHandlers(
     : null
 
   const hasAttr = (target: RawProps, key: string) => {
-    if (key === '$' || isProp(key) || isEmitListener(emitsOptions, key)) {
-      return false
-    }
-    const dynamicSources = target.$
-    if (dynamicSources) {
-      let i = dynamicSources.length
-      while (i--) {
-        if (hasOwn(resolveSource(dynamicSources[i]), key)) {
-          return true
+    if (isAttr(key)) {
+      const dynamicSources = target.$
+      if (dynamicSources) {
+        let i = dynamicSources.length
+        while (i--) {
+          if (hasOwn(resolveSource(dynamicSources[i]), key)) {
+            return true
+          }
         }
       }
+      return hasOwn(target, key)
+    } else {
+      return false
     }
-    return hasOwn(target, key)
   }
 
   const attrsHandlers = {
@@ -123,15 +128,22 @@ export function getPropsProxyHandlers(
       }
     },
     ownKeys(target) {
-      const keys = Object.keys(target)
+      const keys: string[] = []
+      for (const key in target) {
+        if (isAttr(key)) keys.push(key)
+      }
       const dynamicSources = target.$
       if (dynamicSources) {
         let i = dynamicSources.length
+        let source
         while (i--) {
-          keys.push(...Object.keys(resolveSource(dynamicSources[i])))
+          source = resolveSource(dynamicSources[i])
+          for (const key in source) {
+            if (isAttr(key)) keys.push(key)
+          }
         }
       }
-      return keys.filter(key => hasAttr(target, key))
+      return Array.from(new Set(keys))
     },
     set: NO,
     deleteProperty: NO,
index 55c34ffe6c2b3d5e34658135b89dad1701e15afe..11b58a6361ddfcb756515ca3aaeb116818ebac3d 100644 (file)
@@ -7,6 +7,11 @@ export const EMPTY_ARR: readonly never[] = __DEV__ ? Object.freeze([]) : []
 
 export const NOOP = (): void => {}
 
+/**
+ * Always return true.
+ */
+export const YES = () => true
+
 /**
  * Always return false.
  */