]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(runtime-core): add special property to get class component options (#821)
authorKatashin <ktsn55@gmail.com>
Thu, 12 Mar 2020 15:46:32 +0000 (23:46 +0800)
committerGitHub <noreply@github.com>
Thu, 12 Mar 2020 15:46:32 +0000 (11:46 -0400)
packages/runtime-core/__tests__/vnode.spec.ts
packages/runtime-core/src/component.ts
packages/runtime-core/src/h.ts
packages/runtime-core/src/vnode.ts

index 8895938182ffe64b7c861f0ddd544e0fb5c3192a..040e2f6bb2146932172f2567be5aa122f6f3a4cc 100644 (file)
@@ -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' })
index 5bccb756d322197ef09ffa27b6e263264664d0eb..bf28cf552dbdc985a2e4f7b08f6d67b4cca2f9cf 100644 (file)
@@ -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 }
 
index 30cb7a90fc5815a9070549e8fb799735c4c7fb0c..e6f07fb1f1f861ef979a47c3ab4a9d5497c5348c 100644 (file)
@@ -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>,
index e122091145dfba8e6d26e3f1a8616d00e6f870e8..272731e8a0502263e191b7f7d2e9d0e94fee4479 100644 (file)
@@ -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.