diff --git a/packages/runtime-core/__tests__/vnode.spec.ts b/packages/runtime-core/__tests__/vnode.spec.ts index 8895938182f..040e2f6bb21 100644 --- a/packages/runtime-core/__tests__/vnode.spec.ts +++ b/packages/runtime-core/__tests__/vnode.spec.ts @@ -46,6 +46,15 @@ describe('vnode', () => { } }) + test('create with class component', () => { + class Component { + $props: any + static __vccOpts = { template: '
' } + } + const vnode = createVNode(Component) + expect(vnode.type).toEqual(Component.__vccOpts) + }) + describe('class normalization', () => { test('string', () => { const vnode = createVNode('p', { class: 'foo baz' }) diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index 05112c70f74..94967d2760c 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -58,13 +58,18 @@ export interface FunctionalComponent extends SFCInternalOptions {
displayName?: string
}
+export interface ClassComponent {
+ new (...args: any[]): ComponentPublicInstance (
type: Constructor ,
diff --git a/packages/runtime-core/src/vnode.ts b/packages/runtime-core/src/vnode.ts
index 46089491191..747c5a4e2ae 100644
--- a/packages/runtime-core/src/vnode.ts
+++ b/packages/runtime-core/src/vnode.ts
@@ -14,7 +14,8 @@ import {
ComponentInternalInstance,
Data,
SetupProxySymbol,
- Component
+ Component,
+ ClassComponent
} from './component'
import { RawSlots } from './componentSlots'
import { isReactive, Ref } from '@vue/reactivity'
@@ -162,7 +163,7 @@ export function setBlockTracking(value: number) {
// A block root keeps track of dynamic nodes within the block in the
// `dynamicChildren` array.
export function createBlock(
- type: VNodeTypes,
+ type: VNodeTypes | ClassComponent,
props?: { [key: string]: any } | null,
children?: any,
patchFlag?: number,
@@ -203,7 +204,7 @@ export function isSameVNodeType(n1: VNode, n2: VNode): boolean {
}
export function createVNode(
- type: VNodeTypes,
+ type: VNodeTypes | ClassComponent,
props: (Data & VNodeProps) | null = null,
children: unknown = null,
patchFlag: number = 0,
@@ -214,6 +215,11 @@ export function createVNode(
type = Comment
}
+ // class component normalization.
+ if (isFunction(type) && '__vccOpts' in type) {
+ type = type.__vccOpts
+ }
+
// class & style normalization.
if (props !== null) {
// for reactive or proxy objects, we need to clone it to enable mutation.