]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-core): dynamic component should support falsy values without warning
authorEvan You <yyx990803@gmail.com>
Fri, 24 Apr 2020 19:06:21 +0000 (15:06 -0400)
committerEvan You <yyx990803@gmail.com>
Fri, 24 Apr 2020 19:32:47 +0000 (15:32 -0400)
packages/runtime-core/__tests__/helpers/resolveAssets.spec.ts
packages/runtime-core/src/helpers/resolveAssets.ts
packages/runtime-core/src/vnode.ts

index d8088454157ee6b062087374abe213338b632026..6f8957d064ca094d9430332793ab4ae376332622 100644 (file)
@@ -8,7 +8,9 @@ import {
   resolveDynamicComponent,
   h,
   serializeInner,
-  createVNode
+  createVNode,
+  Comment,
+  VNode
 } from '@vue/runtime-test'
 import { mockWarn } from '@vue/shared'
 
@@ -102,6 +104,7 @@ describe('resolveAssets', () => {
         baz: { render: () => 'baz' }
       }
       let foo, bar, baz // dynamic components
+      let dynamicVNode: VNode
 
       const Child = {
         render(this: any) {
@@ -115,6 +118,7 @@ describe('resolveAssets', () => {
           return () => {
             foo = resolveDynamicComponent('foo') // <component is="foo"/>
             bar = resolveDynamicComponent(dynamicComponents.bar) // <component :is="bar"/>, function
+            dynamicVNode = createVNode(resolveDynamicComponent(null)) // <component :is="null"/>
             return h(Child, () => {
               // check inside child slots
               baz = resolveDynamicComponent(dynamicComponents.baz) // <component :is="baz"/>, object
@@ -129,6 +133,8 @@ describe('resolveAssets', () => {
       expect(foo).toBe(dynamicComponents.foo)
       expect(bar).toBe(dynamicComponents.bar)
       expect(baz).toBe(dynamicComponents.baz)
+      // should allow explicit falsy type to remove the component
+      expect(dynamicVNode!.type).toBe(Comment)
     })
 
     test('resolve dynamic component should fallback to plain element without warning', () => {
index 8cb134d52f7b6395ab56c4d054423be614324606..f7118a88fc786c8137ed52fc349178ecd7cdd9e0 100644 (file)
@@ -6,13 +6,7 @@ import {
   ComponentOptions
 } from '../component'
 import { Directive } from '../directives'
-import {
-  camelize,
-  capitalize,
-  isString,
-  isObject,
-  isFunction
-} from '@vue/shared'
+import { camelize, capitalize, isString, isObject } from '@vue/shared'
 import { warn } from '../warning'
 
 const COMPONENTS = 'components'
@@ -22,14 +16,16 @@ export function resolveComponent(name: string): Component | string | undefined {
   return resolveAsset(COMPONENTS, name) || name
 }
 
+export const NULL_DYNAMIC_COMPONENT = Symbol()
+
 export function resolveDynamicComponent(
   component: unknown
-): Component | string | undefined {
-  if (!component) return
+): Component | string | typeof NULL_DYNAMIC_COMPONENT {
   if (isString(component)) {
     return resolveAsset(COMPONENTS, component, false) || component
-  } else if (isFunction(component) || isObject(component)) {
-    return component
+  } else {
+    // invalid types will fallthrough to createVNode and raise warning
+    return (component as any) || NULL_DYNAMIC_COMPONENT
   }
 }
 
index f4de40eff1f5f4670cc49ac03deed89e3c501959..3b21c6abcb4bbea8d5238cffd3e0805813c6194f 100644 (file)
@@ -31,6 +31,7 @@ import { currentScopeId } from './helpers/scopeId'
 import { TeleportImpl, isTeleport } from './components/Teleport'
 import { currentRenderingInstance } from './componentRenderUtils'
 import { RendererNode, RendererElement } from './renderer'
+import { NULL_DYNAMIC_COMPONENT } from './helpers/resolveAssets'
 
 export const Fragment = (Symbol(__DEV__ ? 'Fragment' : undefined) as any) as {
   __isFragment: true
@@ -254,15 +255,15 @@ export const createVNode = (__DEV__
   : _createVNode) as typeof _createVNode
 
 function _createVNode(
-  type: VNodeTypes | ClassComponent,
+  type: VNodeTypes | ClassComponent | typeof NULL_DYNAMIC_COMPONENT,
   props: (Data & VNodeProps) | null = null,
   children: unknown = null,
   patchFlag: number = 0,
   dynamicProps: string[] | null = null,
   isBlockNode = false
 ): VNode {
-  if (!type) {
-    if (__DEV__) {
+  if (!type || type === NULL_DYNAMIC_COMPONENT) {
+    if (__DEV__ && !type) {
       warn(`Invalid vnode type when creating vnode: ${type}.`)
     }
     type = Comment