- v-model and v-show directives are now exposed as public - compiler-used runtime helpers are now exposed for TS tooling, but marked as @private close #1329
107 lines
2.6 KiB
TypeScript
107 lines
2.6 KiB
TypeScript
import { currentRenderingInstance } from '../componentRenderUtils'
|
|
import {
|
|
currentInstance,
|
|
Component,
|
|
FunctionalComponent,
|
|
ComponentOptions
|
|
} from '../component'
|
|
import { Directive } from '../directives'
|
|
import { camelize, capitalize, isString, isObject } from '@vue/shared'
|
|
import { warn } from '../warning'
|
|
|
|
const COMPONENTS = 'components'
|
|
const DIRECTIVES = 'directives'
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
export function resolveComponent(name: string): Component | string | undefined {
|
|
return resolveAsset(COMPONENTS, name) || name
|
|
}
|
|
|
|
export const NULL_DYNAMIC_COMPONENT = Symbol()
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
export function resolveDynamicComponent(
|
|
component: unknown
|
|
): Component | string | typeof NULL_DYNAMIC_COMPONENT {
|
|
if (isString(component)) {
|
|
return resolveAsset(COMPONENTS, component, false) || component
|
|
} else {
|
|
// invalid types will fallthrough to createVNode and raise warning
|
|
return (component as any) || NULL_DYNAMIC_COMPONENT
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
export function resolveDirective(name: string): Directive | undefined {
|
|
return resolveAsset(DIRECTIVES, name)
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* overload 1: components
|
|
*/
|
|
function resolveAsset(
|
|
type: typeof COMPONENTS,
|
|
name: string,
|
|
warnMissing?: boolean
|
|
): Component | undefined
|
|
// overload 2: directives
|
|
function resolveAsset(
|
|
type: typeof DIRECTIVES,
|
|
name: string
|
|
): Directive | undefined
|
|
// implementation
|
|
function resolveAsset(
|
|
type: typeof COMPONENTS | typeof DIRECTIVES,
|
|
name: string,
|
|
warnMissing = true
|
|
) {
|
|
const instance = currentRenderingInstance || currentInstance
|
|
if (instance) {
|
|
let camelized, capitalized
|
|
const registry = instance[type]
|
|
let res =
|
|
registry[name] ||
|
|
registry[(camelized = camelize(name))] ||
|
|
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__) {
|
|
if (res) {
|
|
// in dev, infer anonymous component's name based on registered name
|
|
if (
|
|
type === COMPONENTS &&
|
|
isObject(res) &&
|
|
!(res as ComponentOptions).name
|
|
) {
|
|
;(res as ComponentOptions).name = name
|
|
}
|
|
} else if (warnMissing) {
|
|
warn(`Failed to resolve ${type.slice(0, -1)}: ${name}`)
|
|
}
|
|
}
|
|
return res
|
|
} else if (__DEV__) {
|
|
warn(
|
|
`resolve${capitalize(type.slice(0, -1))} ` +
|
|
`can only be used in render() or setup().`
|
|
)
|
|
}
|
|
}
|