2020-07-24 02:33:15 +08:00
|
|
|
import {
|
|
|
|
currentInstance,
|
2020-08-20 04:11:29 +08:00
|
|
|
ConcreteComponent,
|
2020-12-05 06:03:03 +08:00
|
|
|
ComponentOptions,
|
|
|
|
getComponentName
|
2020-07-24 02:33:15 +08:00
|
|
|
} from '../component'
|
2021-03-06 00:10:06 +08:00
|
|
|
import { currentRenderingInstance } from '../componentRenderContext'
|
2019-09-23 04:50:57 +08:00
|
|
|
import { Directive } from '../directives'
|
2020-06-26 22:07:07 +08:00
|
|
|
import { camelize, capitalize, isString } from '@vue/shared'
|
2019-09-23 04:50:57 +08:00
|
|
|
import { warn } from '../warning'
|
2020-07-08 00:43:05 +08:00
|
|
|
import { VNodeTypes } from '../vnode'
|
2019-09-23 04:50:57 +08:00
|
|
|
|
2021-04-20 00:08:26 +08:00
|
|
|
export const COMPONENTS = 'components'
|
|
|
|
export const DIRECTIVES = 'directives'
|
|
|
|
export const FILTERS = 'filters'
|
|
|
|
|
|
|
|
export type AssetTypes = typeof COMPONENTS | typeof DIRECTIVES | typeof FILTERS
|
2019-12-02 12:17:00 +08:00
|
|
|
|
2020-06-11 02:57:21 +08:00
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
*/
|
2021-03-26 22:04:29 +08:00
|
|
|
export function resolveComponent(
|
|
|
|
name: string,
|
|
|
|
maybeSelfReference?: boolean
|
|
|
|
): ConcreteComponent | string {
|
|
|
|
return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name
|
2019-09-23 04:50:57 +08:00
|
|
|
}
|
|
|
|
|
2023-02-21 17:42:06 +08:00
|
|
|
export const NULL_DYNAMIC_COMPONENT = Symbol.for('v-ndc')
|
2020-04-25 03:06:21 +08:00
|
|
|
|
2020-06-11 02:57:21 +08:00
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
*/
|
2020-07-08 00:43:05 +08:00
|
|
|
export function resolveDynamicComponent(component: unknown): VNodeTypes {
|
2019-10-19 00:09:04 +08:00
|
|
|
if (isString(component)) {
|
2020-03-26 03:08:15 +08:00
|
|
|
return resolveAsset(COMPONENTS, component, false) || component
|
2020-04-25 03:06:21 +08:00
|
|
|
} else {
|
|
|
|
// invalid types will fallthrough to createVNode and raise warning
|
2020-07-08 00:43:05 +08:00
|
|
|
return (component || NULL_DYNAMIC_COMPONENT) as any
|
2019-10-19 00:09:04 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 02:57:21 +08:00
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
*/
|
2019-09-23 04:50:57 +08:00
|
|
|
export function resolveDirective(name: string): Directive | undefined {
|
2019-12-02 12:17:00 +08:00
|
|
|
return resolveAsset(DIRECTIVES, name)
|
2019-09-23 04:50:57 +08:00
|
|
|
}
|
|
|
|
|
2021-04-20 00:08:26 +08:00
|
|
|
/**
|
|
|
|
* v2 compat only
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
export function resolveFilter(name: string): Function | undefined {
|
|
|
|
return resolveAsset(FILTERS, name)
|
|
|
|
}
|
|
|
|
|
2020-06-11 02:57:21 +08:00
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
* overload 1: components
|
|
|
|
*/
|
2019-11-25 23:04:40 +08:00
|
|
|
function resolveAsset(
|
2019-12-02 12:17:00 +08:00
|
|
|
type: typeof COMPONENTS,
|
2019-11-25 23:04:40 +08:00
|
|
|
name: string,
|
2021-03-26 22:04:29 +08:00
|
|
|
warnMissing?: boolean,
|
|
|
|
maybeSelfReference?: boolean
|
2020-08-20 04:11:29 +08:00
|
|
|
): ConcreteComponent | undefined
|
2019-10-05 22:09:34 +08:00
|
|
|
// overload 2: directives
|
2019-11-25 23:04:40 +08:00
|
|
|
function resolveAsset(
|
2019-12-02 12:17:00 +08:00
|
|
|
type: typeof DIRECTIVES,
|
2020-03-26 03:08:15 +08:00
|
|
|
name: string
|
2019-11-25 23:04:40 +08:00
|
|
|
): Directive | undefined
|
2020-06-11 02:57:21 +08:00
|
|
|
// implementation
|
2021-04-20 00:08:26 +08:00
|
|
|
// overload 3: filters (compat only)
|
|
|
|
function resolveAsset(type: typeof FILTERS, name: string): Function | undefined
|
|
|
|
// implementation
|
2019-11-25 23:04:40 +08:00
|
|
|
function resolveAsset(
|
2021-04-20 00:08:26 +08:00
|
|
|
type: AssetTypes,
|
2019-11-25 23:04:40 +08:00
|
|
|
name: string,
|
2021-03-26 22:04:29 +08:00
|
|
|
warnMissing = true,
|
|
|
|
maybeSelfReference = false
|
2019-11-25 23:04:40 +08:00
|
|
|
) {
|
2020-03-26 03:08:15 +08:00
|
|
|
const instance = currentRenderingInstance || currentInstance
|
2019-09-23 04:50:57 +08:00
|
|
|
if (instance) {
|
2020-07-24 02:33:15 +08:00
|
|
|
const Component = instance.type
|
|
|
|
|
2021-03-26 22:04:29 +08:00
|
|
|
// explicit self name has highest priority
|
2020-07-24 02:33:15 +08:00
|
|
|
if (type === COMPONENTS) {
|
2022-06-06 17:36:47 +08:00
|
|
|
const selfName = getComponentName(
|
|
|
|
Component,
|
|
|
|
false /* do not include inferred name to avoid breaking existing code */
|
|
|
|
)
|
2019-12-02 12:17:00 +08:00
|
|
|
if (
|
|
|
|
selfName &&
|
|
|
|
(selfName === name ||
|
2020-07-24 02:33:15 +08:00
|
|
|
selfName === camelize(name) ||
|
|
|
|
selfName === capitalize(camelize(name)))
|
2019-12-02 12:17:00 +08:00
|
|
|
) {
|
2020-07-24 02:33:15 +08:00
|
|
|
return Component
|
2019-12-02 12:17:00 +08:00
|
|
|
}
|
|
|
|
}
|
2020-07-24 02:33:15 +08:00
|
|
|
|
|
|
|
const res =
|
|
|
|
// local registration
|
2021-06-03 02:37:27 +08:00
|
|
|
// check instance[type] first which is resolved for options API
|
2020-08-27 06:09:54 +08:00
|
|
|
resolve(instance[type] || (Component as ComponentOptions)[type], name) ||
|
2020-07-24 02:33:15 +08:00
|
|
|
// global registration
|
|
|
|
resolve(instance.appContext[type], name)
|
2021-03-26 22:04:29 +08:00
|
|
|
|
|
|
|
if (!res && maybeSelfReference) {
|
|
|
|
// fallback to implicit self-reference
|
|
|
|
return Component
|
|
|
|
}
|
|
|
|
|
2020-06-26 21:28:15 +08:00
|
|
|
if (__DEV__ && warnMissing && !res) {
|
2021-09-17 22:01:04 +08:00
|
|
|
const extra =
|
|
|
|
type === COMPONENTS
|
|
|
|
? `\nIf this is a native custom element, make sure to exclude it from ` +
|
|
|
|
`component resolution via compilerOptions.isCustomElement.`
|
|
|
|
: ``
|
|
|
|
warn(`Failed to resolve ${type.slice(0, -1)}: ${name}${extra}`)
|
2019-09-23 04:50:57 +08:00
|
|
|
}
|
2021-03-26 22:04:29 +08:00
|
|
|
|
2019-09-23 04:50:57 +08:00
|
|
|
return res
|
|
|
|
} else if (__DEV__) {
|
|
|
|
warn(
|
|
|
|
`resolve${capitalize(type.slice(0, -1))} ` +
|
|
|
|
`can only be used in render() or setup().`
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
2020-07-24 02:33:15 +08:00
|
|
|
|
|
|
|
function resolve(registry: Record<string, any> | undefined, name: string) {
|
|
|
|
return (
|
|
|
|
registry &&
|
|
|
|
(registry[name] ||
|
|
|
|
registry[camelize(name)] ||
|
|
|
|
registry[capitalize(camelize(name))])
|
|
|
|
)
|
|
|
|
}
|