-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
/
resolveAssets.ts
132 lines (118 loc) · 3.25 KB
/
resolveAssets.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import {
currentInstance,
ConcreteComponent,
ComponentOptions,
getComponentName
} from '../component'
import { currentRenderingInstance } from '../componentRenderContext'
import { Directive } from '../directives'
import { camelize, capitalize, isString } from '@vue/shared'
import { warn } from '../warning'
import { VNodeTypes } from '../vnode'
export const COMPONENTS = 'components'
export const DIRECTIVES = 'directives'
export const FILTERS = 'filters'
export type AssetTypes = typeof COMPONENTS | typeof DIRECTIVES | typeof FILTERS
/**
* @private
*/
export function resolveComponent(
name: string,
maybeSelfReference?: boolean
): ConcreteComponent | string {
return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name
}
export const NULL_DYNAMIC_COMPONENT = Symbol()
/**
* @private
*/
export function resolveDynamicComponent(component: unknown): VNodeTypes {
if (isString(component)) {
return resolveAsset(COMPONENTS, component, false) || component
} else {
// invalid types will fallthrough to createVNode and raise warning
return (component || NULL_DYNAMIC_COMPONENT) as any
}
}
/**
* @private
*/
export function resolveDirective(name: string): Directive | undefined {
return resolveAsset(DIRECTIVES, name)
}
/**
* v2 compat only
* @internal
*/
export function resolveFilter(name: string): Function | undefined {
return resolveAsset(FILTERS, name)
}
/**
* @private
* overload 1: components
*/
function resolveAsset(
type: typeof COMPONENTS,
name: string,
warnMissing?: boolean,
maybeSelfReference?: boolean
): ConcreteComponent | undefined
// overload 2: directives
function resolveAsset(
type: typeof DIRECTIVES,
name: string
): Directive | undefined
// implementation
// overload 3: filters (compat only)
function resolveAsset(type: typeof FILTERS, name: string): Function | undefined
// implementation
function resolveAsset(
type: AssetTypes,
name: string,
warnMissing = true,
maybeSelfReference = false
) {
const instance = currentRenderingInstance || currentInstance
if (instance) {
const Component = instance.type
// explicit self name has highest priority
if (type === COMPONENTS) {
const selfName = getComponentName(Component)
if (
selfName &&
(selfName === name ||
selfName === camelize(name) ||
selfName === capitalize(camelize(name)))
) {
return Component
}
}
const res =
// local registration
// check instance[type] first for components with mixin or extends.
resolve(instance[type] || (Component as ComponentOptions)[type], name) ||
// global registration
resolve(instance.appContext[type], name)
if (!res && maybeSelfReference) {
// fallback to implicit self-reference
return Component
}
if (__DEV__ && warnMissing && !res) {
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().`
)
}
}
function resolve(registry: Record<string, any> | undefined, name: string) {
return (
registry &&
(registry[name] ||
registry[camelize(name)] ||
registry[capitalize(camelize(name))])
)
}