Skip to content

Commit ded92f9

Browse files
committed
fix(runtime-core): dynamic component should support falsy values without warning
1 parent f3a9b51 commit ded92f9

File tree

3 files changed

+18
-15
lines changed

3 files changed

+18
-15
lines changed

packages/runtime-core/__tests__/helpers/resolveAssets.spec.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import {
88
resolveDynamicComponent,
99
h,
1010
serializeInner,
11-
createVNode
11+
createVNode,
12+
Comment,
13+
VNode
1214
} from '@vue/runtime-test'
1315
import { mockWarn } from '@vue/shared'
1416

@@ -102,6 +104,7 @@ describe('resolveAssets', () => {
102104
baz: { render: () => 'baz' }
103105
}
104106
let foo, bar, baz // dynamic components
107+
let dynamicVNode: VNode
105108

106109
const Child = {
107110
render(this: any) {
@@ -115,6 +118,7 @@ describe('resolveAssets', () => {
115118
return () => {
116119
foo = resolveDynamicComponent('foo') // <component is="foo"/>
117120
bar = resolveDynamicComponent(dynamicComponents.bar) // <component :is="bar"/>, function
121+
dynamicVNode = createVNode(resolveDynamicComponent(null)) // <component :is="null"/>
118122
return h(Child, () => {
119123
// check inside child slots
120124
baz = resolveDynamicComponent(dynamicComponents.baz) // <component :is="baz"/>, object
@@ -129,6 +133,8 @@ describe('resolveAssets', () => {
129133
expect(foo).toBe(dynamicComponents.foo)
130134
expect(bar).toBe(dynamicComponents.bar)
131135
expect(baz).toBe(dynamicComponents.baz)
136+
// should allow explicit falsy type to remove the component
137+
expect(dynamicVNode!.type).toBe(Comment)
132138
})
133139

134140
test('resolve dynamic component should fallback to plain element without warning', () => {

packages/runtime-core/src/helpers/resolveAssets.ts

+7-11
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,7 @@ import {
66
ComponentOptions
77
} from '../component'
88
import { Directive } from '../directives'
9-
import {
10-
camelize,
11-
capitalize,
12-
isString,
13-
isObject,
14-
isFunction
15-
} from '@vue/shared'
9+
import { camelize, capitalize, isString, isObject } from '@vue/shared'
1610
import { warn } from '../warning'
1711

1812
const COMPONENTS = 'components'
@@ -22,14 +16,16 @@ export function resolveComponent(name: string): Component | string | undefined {
2216
return resolveAsset(COMPONENTS, name) || name
2317
}
2418

19+
export const NULL_DYNAMIC_COMPONENT = Symbol()
20+
2521
export function resolveDynamicComponent(
2622
component: unknown
27-
): Component | string | undefined {
28-
if (!component) return
23+
): Component | string | typeof NULL_DYNAMIC_COMPONENT {
2924
if (isString(component)) {
3025
return resolveAsset(COMPONENTS, component, false) || component
31-
} else if (isFunction(component) || isObject(component)) {
32-
return component
26+
} else {
27+
// invalid types will fallthrough to createVNode and raise warning
28+
return (component as any) || NULL_DYNAMIC_COMPONENT
3329
}
3430
}
3531

packages/runtime-core/src/vnode.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { currentScopeId } from './helpers/scopeId'
3131
import { TeleportImpl, isTeleport } from './components/Teleport'
3232
import { currentRenderingInstance } from './componentRenderUtils'
3333
import { RendererNode, RendererElement } from './renderer'
34+
import { NULL_DYNAMIC_COMPONENT } from './helpers/resolveAssets'
3435

3536
export const Fragment = (Symbol(__DEV__ ? 'Fragment' : undefined) as any) as {
3637
__isFragment: true
@@ -254,15 +255,15 @@ export const createVNode = (__DEV__
254255
: _createVNode) as typeof _createVNode
255256

256257
function _createVNode(
257-
type: VNodeTypes | ClassComponent,
258+
type: VNodeTypes | ClassComponent | typeof NULL_DYNAMIC_COMPONENT,
258259
props: (Data & VNodeProps) | null = null,
259260
children: unknown = null,
260261
patchFlag: number = 0,
261262
dynamicProps: string[] | null = null,
262263
isBlockNode = false
263264
): VNode {
264-
if (!type) {
265-
if (__DEV__) {
265+
if (!type || type === NULL_DYNAMIC_COMPONENT) {
266+
if (__DEV__ && !type) {
266267
warn(`Invalid vnode type when creating vnode: ${type}.`)
267268
}
268269
type = Comment

0 commit comments

Comments
 (0)