fix(runtime-core): fix props/emits resolving with global mixins
fix #1975
This commit is contained in:
@@ -31,6 +31,7 @@ import {
|
||||
} from './component'
|
||||
import { isEmitListener } from './componentEmits'
|
||||
import { InternalObjectKey } from './vnode'
|
||||
import { AppContext } from './apiCreateApp'
|
||||
|
||||
export type ComponentPropsOptions<P = Data> =
|
||||
| ComponentObjectPropsOptions<P>
|
||||
@@ -107,7 +108,8 @@ type NormalizedProp =
|
||||
|
||||
// normalized value is a tuple of the actual normalized options
|
||||
// and an array of prop keys that need value casting (booleans and defaults)
|
||||
export type NormalizedPropsOptions = [Record<string, NormalizedProp>, string[]]
|
||||
export type NormalizedProps = Record<string, NormalizedProp>
|
||||
export type NormalizedPropsOptions = [NormalizedProps, string[]] | []
|
||||
|
||||
export function initProps(
|
||||
instance: ComponentInternalInstance,
|
||||
@@ -121,7 +123,7 @@ export function initProps(
|
||||
setFullProps(instance, rawProps, props, attrs)
|
||||
// validation
|
||||
if (__DEV__) {
|
||||
validateProps(props, instance.type)
|
||||
validateProps(props, instance)
|
||||
}
|
||||
|
||||
if (isStateful) {
|
||||
@@ -151,7 +153,7 @@ export function updateProps(
|
||||
vnode: { patchFlag }
|
||||
} = instance
|
||||
const rawCurrentProps = toRaw(props)
|
||||
const [options] = normalizePropsOptions(instance.type)
|
||||
const [options] = instance.propsOptions
|
||||
|
||||
if (
|
||||
// always force full diff if hmr is enabled
|
||||
@@ -236,7 +238,7 @@ export function updateProps(
|
||||
trigger(instance, TriggerOpTypes.SET, '$attrs')
|
||||
|
||||
if (__DEV__ && rawProps) {
|
||||
validateProps(props, instance.type)
|
||||
validateProps(props, instance)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,7 +248,7 @@ function setFullProps(
|
||||
props: Data,
|
||||
attrs: Data
|
||||
) {
|
||||
const [options, needCastKeys] = normalizePropsOptions(instance.type)
|
||||
const [options, needCastKeys] = instance.propsOptions
|
||||
if (rawProps) {
|
||||
for (const key in rawProps) {
|
||||
const value = rawProps[key]
|
||||
@@ -259,7 +261,7 @@ function setFullProps(
|
||||
let camelKey
|
||||
if (options && hasOwn(options, (camelKey = camelize(key)))) {
|
||||
props[camelKey] = value
|
||||
} else if (!isEmitListener(instance.type, key)) {
|
||||
} else if (!isEmitListener(instance.emitsOptions, key)) {
|
||||
// Any non-declared (either as a prop or an emitted event) props are put
|
||||
// into a separate `attrs` object for spreading. Make sure to preserve
|
||||
// original key casing
|
||||
@@ -283,7 +285,7 @@ function setFullProps(
|
||||
}
|
||||
|
||||
function resolvePropValue(
|
||||
options: NormalizedPropsOptions[0],
|
||||
options: NormalizedProps,
|
||||
props: Data,
|
||||
key: string,
|
||||
value: unknown
|
||||
@@ -315,10 +317,15 @@ function resolvePropValue(
|
||||
}
|
||||
|
||||
export function normalizePropsOptions(
|
||||
comp: ConcreteComponent
|
||||
): NormalizedPropsOptions | [] {
|
||||
if (comp.__props) {
|
||||
return comp.__props
|
||||
comp: ConcreteComponent,
|
||||
appContext: AppContext,
|
||||
asMixin = false
|
||||
): NormalizedPropsOptions {
|
||||
const appId = appContext.app ? appContext.app._uid : -1
|
||||
const cache = comp.__props || (comp.__props = {})
|
||||
const cached = cache[appId]
|
||||
if (cached) {
|
||||
return cached
|
||||
}
|
||||
|
||||
const raw = comp.props
|
||||
@@ -329,22 +336,24 @@ export function normalizePropsOptions(
|
||||
let hasExtends = false
|
||||
if (__FEATURE_OPTIONS_API__ && !isFunction(comp)) {
|
||||
const extendProps = (raw: ComponentOptions) => {
|
||||
const [props, keys] = normalizePropsOptions(raw)
|
||||
hasExtends = true
|
||||
const [props, keys] = normalizePropsOptions(raw, appContext, true)
|
||||
extend(normalized, props)
|
||||
if (keys) needCastKeys.push(...keys)
|
||||
}
|
||||
if (!asMixin && appContext.mixins.length) {
|
||||
appContext.mixins.forEach(extendProps)
|
||||
}
|
||||
if (comp.extends) {
|
||||
hasExtends = true
|
||||
extendProps(comp.extends)
|
||||
}
|
||||
if (comp.mixins) {
|
||||
hasExtends = true
|
||||
comp.mixins.forEach(extendProps)
|
||||
}
|
||||
}
|
||||
|
||||
if (!raw && !hasExtends) {
|
||||
return (comp.__props = EMPTY_ARR)
|
||||
return (cache[appId] = EMPTY_ARR)
|
||||
}
|
||||
|
||||
if (isArray(raw)) {
|
||||
@@ -381,9 +390,8 @@ export function normalizePropsOptions(
|
||||
}
|
||||
}
|
||||
}
|
||||
const normalizedEntry: NormalizedPropsOptions = [normalized, needCastKeys]
|
||||
comp.__props = normalizedEntry
|
||||
return normalizedEntry
|
||||
|
||||
return (cache[appId] = [normalized, needCastKeys])
|
||||
}
|
||||
|
||||
// use function string name to check type constructors
|
||||
@@ -416,9 +424,9 @@ function getTypeIndex(
|
||||
/**
|
||||
* dev only
|
||||
*/
|
||||
function validateProps(props: Data, comp: ConcreteComponent) {
|
||||
function validateProps(props: Data, instance: ComponentInternalInstance) {
|
||||
const rawValues = toRaw(props)
|
||||
const options = normalizePropsOptions(comp)[0]
|
||||
const options = instance.propsOptions[0]
|
||||
for (const key in options) {
|
||||
let opt = options[key]
|
||||
if (opt == null) continue
|
||||
|
||||
Reference in New Issue
Block a user