feat(core): support recursively resolving self component by name

This commit is contained in:
Evan You 2019-12-01 23:17:00 -05:00
parent c8895e7cb9
commit f5f2dca132

View File

@ -2,7 +2,8 @@ import { currentRenderingInstance } from '../componentRenderUtils'
import { import {
currentInstance, currentInstance,
Component, Component,
ComponentInternalInstance ComponentInternalInstance,
FunctionalComponent
} from '../component' } from '../component'
import { Directive } from '../directives' import { Directive } from '../directives'
import { import {
@ -14,8 +15,11 @@ import {
} from '@vue/shared' } from '@vue/shared'
import { warn } from '../warning' import { warn } from '../warning'
const COMPONENTS = 'components'
const DIRECTIVES = 'directives'
export function resolveComponent(name: string): Component | undefined { export function resolveComponent(name: string): Component | undefined {
return resolveAsset('components', name) return resolveAsset(COMPONENTS, name)
} }
export function resolveDynamicComponent( export function resolveDynamicComponent(
@ -28,42 +32,54 @@ export function resolveDynamicComponent(
): Component | undefined { ): Component | undefined {
if (!component) return if (!component) return
if (isString(component)) { if (isString(component)) {
return resolveAsset('components', component, instance) return resolveAsset(COMPONENTS, component, instance)
} else if (isFunction(component) || isObject(component)) { } else if (isFunction(component) || isObject(component)) {
return component return component
} }
} }
export function resolveDirective(name: string): Directive | undefined { export function resolveDirective(name: string): Directive | undefined {
return resolveAsset('directives', name) return resolveAsset(DIRECTIVES, name)
} }
// overload 1: components // overload 1: components
function resolveAsset( function resolveAsset(
type: 'components', type: typeof COMPONENTS,
name: string, name: string,
instance?: ComponentInternalInstance instance?: ComponentInternalInstance
): Component | undefined ): Component | undefined
// overload 2: directives // overload 2: directives
function resolveAsset( function resolveAsset(
type: 'directives', type: typeof DIRECTIVES,
name: string, name: string,
instance?: ComponentInternalInstance instance?: ComponentInternalInstance
): Directive | undefined ): Directive | undefined
function resolveAsset( function resolveAsset(
type: 'components' | 'directives', type: typeof COMPONENTS | typeof DIRECTIVES,
name: string, name: string,
instance: ComponentInternalInstance | null = currentRenderingInstance || instance: ComponentInternalInstance | null = currentRenderingInstance ||
currentInstance currentInstance
) { ) {
if (instance) { if (instance) {
let camelized let camelized, capitalized
const registry = instance[type] const registry = instance[type]
const res = let res =
registry[name] || registry[name] ||
registry[(camelized = camelize(name))] || registry[(camelized = camelize(name))] ||
registry[capitalize(camelized)] registry[(capitalized = capitalize(camelized))]
if (!res && type === COMPONENTS) {
const self = instance.type
const selfName = (self as FunctionalComponent).displayName || self.name
if (
selfName &&
(selfName === name ||
selfName === camelized ||
selfName === capitalized)
) {
res = self
}
}
if (__DEV__ && !res) { if (__DEV__ && !res) {
warn(`Failed to resolve ${type.slice(0, -1)}: ${name}`) warn(`Failed to resolve ${type.slice(0, -1)}: ${name}`)
} }