wip: handle props case matching

This commit is contained in:
Evan You 2024-12-05 17:33:39 +08:00
parent 93a16af08e
commit fc9aa62248
No known key found for this signature in database
GPG Key ID: 00E9AB7A6704CE0A
2 changed files with 64 additions and 33 deletions

View File

@ -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 { VaporComponent, VaporComponentInstance } from './component'
import { import {
type NormalizedPropsOptions, type NormalizedPropsOptions,
@ -56,10 +64,54 @@ export function getPropsProxyHandlers(
) )
: passThrough : passThrough
const getProp = (target: RawProps, key: string, asProp: boolean) => { const getProp = (target: RawProps, key: string) => {
if (asProp) { if (key === '$' || !isProp(key)) {
if (!isProp(key) || key === '$') return return
} else if (isProp(key) || isEmitListener(emitsOptions, key)) { }
const dynamicSources = target.$
if (dynamicSources) {
let i = dynamicSources.length
let source, isDynamic, rawKey
while (i--) {
source = dynamicSources[i]
isDynamic = isFunction(source)
source = isDynamic ? (source as Function)() : source
for (rawKey in source) {
if (camelize(rawKey) === key) {
return castProp(isDynamic ? source[rawKey] : source[rawKey](), 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),
has: (_, key: string) => isProp(key),
getOwnPropertyDescriptor(target, key: string) {
if (isProp(key)) {
return {
configurable: true,
enumerable: true,
get: () => getProp(target, key),
}
}
},
ownKeys: () => Object.keys(propsOptions),
set: NO,
deleteProperty: NO,
} satisfies ProxyHandler<RawProps>)
: null
const getAttr = (target: RawProps, key: string) => {
if (isProp(key) || isEmitListener(emitsOptions, key)) {
return return
} }
const dynamicSources = target.$ const dynamicSources = target.$
@ -71,35 +123,15 @@ export function getPropsProxyHandlers(
isDynamic = isFunction(source) isDynamic = isFunction(source)
source = isDynamic ? (source as Function)() : source source = isDynamic ? (source as Function)() : source
if (hasOwn(source, key)) { if (hasOwn(source, key)) {
return castProp(isDynamic ? source[key] : source[key](), key) return isDynamic ? source[key] : source[key]()
} }
} }
} }
if (key in target) { if (hasOwn(target, key)) {
return castProp(target[key as string](), key) return target[key]
} }
return castProp(undefined, key, true)
} }
const propsHandlers = propsOptions
? ({
get: (target, key: string) => getProp(target, key, true),
has: (_, key: string) => isProp(key),
getOwnPropertyDescriptor(target, key: string) {
if (isProp(key)) {
return {
configurable: true,
enumerable: true,
get: () => getProp(target, key, true),
}
}
},
ownKeys: () => Object.keys(propsOptions),
set: NO,
deleteProperty: NO,
} satisfies ProxyHandler<RawProps>)
: null
const hasAttr = (target: RawProps, key: string) => { const hasAttr = (target: RawProps, key: string) => {
if (isAttr(key)) { if (isAttr(key)) {
const dynamicSources = target.$ const dynamicSources = target.$
@ -119,7 +151,7 @@ export function getPropsProxyHandlers(
const attrsHandlers = { const attrsHandlers = {
get: (target, key: string) => { get: (target, key: string) => {
return getProp(target, key, false) return getAttr(target, key)
}, },
has: hasAttr, has: hasAttr,
getOwnPropertyDescriptor(target, key: string) { getOwnPropertyDescriptor(target, key: string) {
@ -127,7 +159,7 @@ export function getPropsProxyHandlers(
return { return {
configurable: true, configurable: true,
enumerable: true, enumerable: true,
get: () => getProp(target, key, false), get: () => getAttr(target, key),
} }
} }
}, },

View File

@ -117,13 +117,12 @@ const cacheStringFunction = <T extends (str: string) => string>(fn: T): T => {
} }
const camelizeRE = /-(\w)/g const camelizeRE = /-(\w)/g
const camelizeReplacer = (_: any, c: string) => (c ? c.toUpperCase() : '')
/** /**
* @private * @private
*/ */
export const camelize: (str: string) => string = cacheStringFunction( export const camelize: (str: string) => string = cacheStringFunction(
(str: string): string => { (str: string): string => str.replace(camelizeRE, camelizeReplacer),
return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''))
},
) )
const hyphenateRE = /\B([A-Z])/g const hyphenateRE = /\B([A-Z])/g