mirror of https://github.com/vuejs/core.git
perf(runtime-core): improve efficiency of normalizePropsOptions (#11409)
close #9739
This commit is contained in:
parent
87923f6af1
commit
5680142e68
|
@ -174,12 +174,10 @@ export type ExtractDefaultPropTypes<O> = O extends object
|
|||
{ [K in keyof Pick<O, DefaultKeys<O>>]: InferPropType<O[K]> }
|
||||
: {}
|
||||
|
||||
type NormalizedProp =
|
||||
| null
|
||||
| (PropOptions & {
|
||||
[BooleanFlags.shouldCast]?: boolean
|
||||
[BooleanFlags.shouldCastTrue]?: boolean
|
||||
})
|
||||
type NormalizedProp = PropOptions & {
|
||||
[BooleanFlags.shouldCast]?: boolean
|
||||
[BooleanFlags.shouldCastTrue]?: boolean
|
||||
}
|
||||
|
||||
// normalized value is a tuple of the actual normalized options
|
||||
// and an array of prop keys that need value casting (booleans and defaults)
|
||||
|
@ -564,16 +562,36 @@ export function normalizePropsOptions(
|
|||
const opt = raw[key]
|
||||
const prop: NormalizedProp = (normalized[normalizedKey] =
|
||||
isArray(opt) || isFunction(opt) ? { type: opt } : extend({}, opt))
|
||||
if (prop) {
|
||||
const booleanIndex = getTypeIndex(Boolean, prop.type)
|
||||
const stringIndex = getTypeIndex(String, prop.type)
|
||||
prop[BooleanFlags.shouldCast] = booleanIndex > -1
|
||||
prop[BooleanFlags.shouldCastTrue] =
|
||||
stringIndex < 0 || booleanIndex < stringIndex
|
||||
// if the prop needs boolean casting or default value
|
||||
if (booleanIndex > -1 || hasOwn(prop, 'default')) {
|
||||
needCastKeys.push(normalizedKey)
|
||||
const propType = prop.type
|
||||
let shouldCast = false
|
||||
let shouldCastTrue = true
|
||||
|
||||
if (isArray(propType)) {
|
||||
for (let index = 0; index < propType.length; ++index) {
|
||||
const type = propType[index]
|
||||
const typeName = isFunction(type) && type.name
|
||||
|
||||
if (typeName === 'Boolean') {
|
||||
shouldCast = true
|
||||
break
|
||||
} else if (typeName === 'String') {
|
||||
// If we find `String` before `Boolean`, e.g. `[String, Boolean]`,
|
||||
// we need to handle the casting slightly differently. Props
|
||||
// passed as `<Comp checked="">` or `<Comp checked="checked">`
|
||||
// will either be treated as strings or converted to a boolean
|
||||
// `true`, depending on the order of the types.
|
||||
shouldCastTrue = false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
shouldCast = isFunction(propType) && propType.name === 'Boolean'
|
||||
}
|
||||
|
||||
prop[BooleanFlags.shouldCast] = shouldCast
|
||||
prop[BooleanFlags.shouldCastTrue] = shouldCastTrue
|
||||
// if the prop needs boolean casting or default value
|
||||
if (shouldCast || hasOwn(prop, 'default')) {
|
||||
needCastKeys.push(normalizedKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -595,6 +613,7 @@ function validatePropName(key: string) {
|
|||
return false
|
||||
}
|
||||
|
||||
// dev only
|
||||
// use function string name to check type constructors
|
||||
// so that it works across vms / iframes.
|
||||
function getType(ctor: Prop<any>): string {
|
||||
|
@ -617,22 +636,6 @@ function getType(ctor: Prop<any>): string {
|
|||
return ''
|
||||
}
|
||||
|
||||
function isSameType(a: Prop<any>, b: Prop<any>): boolean {
|
||||
return getType(a) === getType(b)
|
||||
}
|
||||
|
||||
function getTypeIndex(
|
||||
type: Prop<any>,
|
||||
expectedTypes: PropType<any> | void | null | true,
|
||||
): number {
|
||||
if (isArray(expectedTypes)) {
|
||||
return expectedTypes.findIndex(t => isSameType(t, type))
|
||||
} else if (isFunction(expectedTypes)) {
|
||||
return isSameType(expectedTypes, type) ? 0 : -1
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
/**
|
||||
* dev only
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue