fix: dynamic component fallback to native element

fix #870
This commit is contained in:
Evan You
2020-03-23 14:47:04 -04:00
parent 1b2149dbb2
commit f529dbde23
7 changed files with 80 additions and 34 deletions

View File

@@ -24,10 +24,14 @@ export function resolveComponent(name: string): Component | undefined {
export function resolveDynamicComponent(
component: unknown
): Component | undefined {
): Component | string | undefined {
if (!component) return
if (isString(component)) {
return resolveAsset(COMPONENTS, component, currentRenderingInstance)
return (
resolveAsset(COMPONENTS, component, currentRenderingInstance, false) ||
// fallback to plain element
component
)
} else if (isFunction(component) || isObject(component)) {
return component
}
@@ -41,7 +45,8 @@ export function resolveDirective(name: string): Directive | undefined {
function resolveAsset(
type: typeof COMPONENTS,
name: string,
instance?: ComponentInternalInstance | null
instance?: ComponentInternalInstance | null,
warnMissing?: boolean
): Component | undefined
// overload 2: directives
function resolveAsset(
@@ -54,7 +59,8 @@ function resolveAsset(
type: typeof COMPONENTS | typeof DIRECTIVES,
name: string,
instance: ComponentInternalInstance | null = currentRenderingInstance ||
currentInstance
currentInstance,
warnMissing = true
) {
if (instance) {
let camelized, capitalized
@@ -75,7 +81,8 @@ function resolveAsset(
res = self
}
}
if (__DEV__ && !res) {
if (__DEV__ && warnMissing && !res) {
debugger
warn(`Failed to resolve ${type.slice(0, -1)}: ${name}`)
}
return res

View File

@@ -397,9 +397,16 @@ export function normalizeChildren(vnode: VNode, children: unknown) {
} else if (isArray(children)) {
type = ShapeFlags.ARRAY_CHILDREN
} else if (typeof children === 'object') {
type = ShapeFlags.SLOTS_CHILDREN
if (!(children as RawSlots)._) {
;(children as RawSlots)._ctx = currentRenderingInstance
// in case <component :is="x"> resolves to native element, the vnode call
// will receive slots object.
if (vnode.shapeFlag & ShapeFlags.ELEMENT && (children as any).default) {
normalizeChildren(vnode, (children as any).default())
return
} else {
type = ShapeFlags.SLOTS_CHILDREN
if (!(children as RawSlots)._) {
;(children as RawSlots)._ctx = currentRenderingInstance
}
}
} else if (isFunction(children)) {
children = { default: children, _ctx: currentRenderingInstance }