From: Evan You Date: Thu, 5 Dec 2024 09:33:39 +0000 (+0800) Subject: wip: handle props case matching X-Git-Tag: v3.6.0-alpha.1~16^2~232 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fc9aa622482a1877a152c31cb753753a599caef2;p=thirdparty%2Fvuejs%2Fcore.git wip: handle props case matching --- diff --git a/packages/runtime-vapor/src/componentProps.ts b/packages/runtime-vapor/src/componentProps.ts index 553975945a..41101a079a 100644 --- a/packages/runtime-vapor/src/componentProps.ts +++ b/packages/runtime-vapor/src/componentProps.ts @@ -1,4 +1,12 @@ -import { EMPTY_ARR, NO, YES, extend, hasOwn, isFunction } from '@vue/shared' +import { + EMPTY_ARR, + NO, + YES, + camelize, + extend, + hasOwn, + isFunction, +} from '@vue/shared' import type { VaporComponent, VaporComponentInstance } from './component' import { type NormalizedPropsOptions, @@ -56,41 +64,43 @@ export function getPropsProxyHandlers( ) : passThrough - const getProp = (target: RawProps, key: string, asProp: boolean) => { - if (asProp) { - if (!isProp(key) || key === '$') return - } else if (isProp(key) || isEmitListener(emitsOptions, key)) { + const getProp = (target: RawProps, key: string) => { + if (key === '$' || !isProp(key)) { return } const dynamicSources = target.$ if (dynamicSources) { let i = dynamicSources.length - let source, isDynamic + let source, isDynamic, rawKey while (i--) { source = dynamicSources[i] isDynamic = isFunction(source) source = isDynamic ? (source as Function)() : source - if (hasOwn(source, key)) { - return castProp(isDynamic ? source[key] : source[key](), key) + for (rawKey in source) { + if (camelize(rawKey) === key) { + return castProp(isDynamic ? source[rawKey] : source[rawKey](), key) + } } } } - if (key in target) { - return castProp(target[key as string](), key) + for (const rawKey in target) { + if (camelize(rawKey) === key) { + return castProp(target[rawKey](), key) + } } return castProp(undefined, key, true) } const propsHandlers = propsOptions ? ({ - get: (target, key: string) => getProp(target, key, true), + get: (target, key: string) => getProp(target, key), has: (_, key: string) => isProp(key), getOwnPropertyDescriptor(target, key: string) { if (isProp(key)) { return { configurable: true, enumerable: true, - get: () => getProp(target, key, true), + get: () => getProp(target, key), } } }, @@ -100,6 +110,28 @@ export function getPropsProxyHandlers( } satisfies ProxyHandler) : null + const getAttr = (target: RawProps, key: string) => { + if (isProp(key) || isEmitListener(emitsOptions, key)) { + return + } + const dynamicSources = target.$ + if (dynamicSources) { + let i = dynamicSources.length + let source, isDynamic + while (i--) { + source = dynamicSources[i] + isDynamic = isFunction(source) + source = isDynamic ? (source as Function)() : source + if (hasOwn(source, key)) { + return isDynamic ? source[key] : source[key]() + } + } + } + if (hasOwn(target, key)) { + return target[key] + } + } + const hasAttr = (target: RawProps, key: string) => { if (isAttr(key)) { const dynamicSources = target.$ @@ -119,7 +151,7 @@ export function getPropsProxyHandlers( const attrsHandlers = { get: (target, key: string) => { - return getProp(target, key, false) + return getAttr(target, key) }, has: hasAttr, getOwnPropertyDescriptor(target, key: string) { @@ -127,7 +159,7 @@ export function getPropsProxyHandlers( return { configurable: true, enumerable: true, - get: () => getProp(target, key, false), + get: () => getAttr(target, key), } } }, diff --git a/packages/shared/src/general.ts b/packages/shared/src/general.ts index 11b58a6361..bf11ba7a29 100644 --- a/packages/shared/src/general.ts +++ b/packages/shared/src/general.ts @@ -117,13 +117,12 @@ const cacheStringFunction = string>(fn: T): T => { } const camelizeRE = /-(\w)/g +const camelizeReplacer = (_: any, c: string) => (c ? c.toUpperCase() : '') /** * @private */ export const camelize: (str: string) => string = cacheStringFunction( - (str: string): string => { - return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : '')) - }, + (str: string): string => str.replace(camelizeRE, camelizeReplacer), ) const hyphenateRE = /\B([A-Z])/g