import { isFunction, NO, isObject } from '@vue/shared'
import { version } from '.'
import { installAppCompatProperties } from './compat/global'
+import { NormalizedPropsOptions } from './componentProps'
+import { ObjectEmitsOptions } from './componentEmits'
export interface App<HostElement = any> {
version: string
* Cache for merged/normalized component options
* Each app instance has its own cache because app-level global mixins and
* optionMergeStrategies can affect merge behavior.
+ * @internal
*/
- cache: WeakMap<ComponentOptions, MergedComponentOptions>
+ optionsCache: WeakMap<ComponentOptions, MergedComponentOptions>
/**
- * Flag for de-optimizing props normalization
+ * Cache for normalized props options
* @internal
*/
- deopt?: boolean
+ propsCache: WeakMap<ConcreteComponent, NormalizedPropsOptions>
+ /**
+ * Cache for normalized emits options
+ * @internal
+ */
+ emitsCache: WeakMap<ConcreteComponent, ObjectEmitsOptions | null>
/**
* HMR only
* @internal
components: {},
directives: {},
provides: Object.create(null),
- cache: new WeakMap()
+ optionsCache: new WeakMap(),
+ propsCache: new WeakMap(),
+ emitsCache: new WeakMap()
}
}
if (__FEATURE_OPTIONS_API__) {
if (!context.mixins.includes(mixin)) {
context.mixins.push(mixin)
- // global mixin with props/emits de-optimizes props/emits
- // normalization caching.
- if (mixin.props || mixin.emits) {
- context.deopt = true
- }
} else if (__DEV__) {
warn(
'Mixin has already been applied to target app' +
appContext: AppContext,
asMixin = false
): ObjectEmitsOptions | null {
- if (!appContext.deopt && comp.__emits !== undefined) {
- return comp.__emits
+ const cache = appContext.emitsCache
+ const cached = cache.get(comp)
+ if (cached !== undefined) {
+ return cached
}
const raw = comp.emits
}
if (!raw && !hasExtends) {
- return (comp.__emits = null)
+ cache.set(comp, null)
+ return null
}
if (isArray(raw)) {
} else {
extend(normalized, raw)
}
- return (comp.__emits = normalized)
+
+ cache.set(comp, normalized)
+ return normalized
}
// Check if an incoming prop key is a declared emit event listener.
appContext: AppContext,
asMixin = false
): NormalizedPropsOptions {
- if (!appContext.deopt && comp.__props) {
- return comp.__props
+ const cache = appContext.propsCache
+ const cached = cache.get(comp)
+ if (cached) {
+ return cached
}
const raw = comp.props
}
if (!raw && !hasExtends) {
- return (comp.__props = EMPTY_ARR as any)
+ cache.set(comp, EMPTY_ARR as any)
+ return EMPTY_ARR as any
}
if (isArray(raw)) {
}
}
- return (comp.__props = [normalized, needCastKeys])
+ const res: NormalizedPropsOptions = [normalized, needCastKeys]
+ cache.set(comp, res)
+ return res
}
function validatePropName(key: string) {