Просмотр исходного кода

feat(runtime-core): add special property to get class component options (#821)

Katashin 6 лет назад
Родитель
Сommit
dd17fa1c90

+ 9 - 0
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: '<div />' }
+    }
+    const vnode = createVNode(Component)
+    expect(vnode.type).toEqual(Component.__vccOpts)
+  })
+
   describe('class normalization', () => {
     test('string', () => {
       const vnode = createVNode('p', { class: 'foo baz' })

+ 6 - 1
packages/runtime-core/src/component.ts

@@ -58,13 +58,18 @@ export interface FunctionalComponent<P = {}> extends SFCInternalOptions {
   displayName?: string
 }
 
+export interface ClassComponent {
+  new (...args: any[]): ComponentPublicInstance<any, any, any, any, any>
+  __vccOpts: ComponentOptions
+}
+
 export type Component = ComponentOptions | FunctionalComponent
 
 // A type used in public APIs where a component type is expected.
 // The constructor type is an artificial type returned by defineComponent().
 export type PublicAPIComponent =
   | Component
-  | { new (): ComponentPublicInstance<any, any, any, any, any> }
+  | { new (...args: any[]): ComponentPublicInstance<any, any, any, any, any> }
 
 export { ComponentOptions }
 

+ 1 - 1
packages/runtime-core/src/h.ts

@@ -130,7 +130,7 @@ export function h<O>(
   children?: RawChildren | RawSlots
 ): VNode
 
-// fake constructor type returned by `defineComponent`
+// fake constructor type returned by `defineComponent` or class component
 export function h(type: Constructor, children?: RawChildren): VNode
 export function h<P>(
   type: Constructor<P>,

+ 9 - 3
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,
@@ -216,6 +217,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.