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

This commit is contained in:
Katashin 2020-03-12 23:46:32 +08:00 committed by GitHub
parent 1e9d1319c3
commit dd17fa1c90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 5 deletions

View 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', () => { describe('class normalization', () => {
test('string', () => { test('string', () => {
const vnode = createVNode('p', { class: 'foo baz' }) const vnode = createVNode('p', { class: 'foo baz' })

View File

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

View File

@ -130,7 +130,7 @@ export function h<O>(
children?: RawChildren | RawSlots children?: RawChildren | RawSlots
): VNode ): 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(type: Constructor, children?: RawChildren): VNode
export function h<P>( export function h<P>(
type: Constructor<P>, type: Constructor<P>,

View File

@ -14,7 +14,8 @@ import {
ComponentInternalInstance, ComponentInternalInstance,
Data, Data,
SetupProxySymbol, SetupProxySymbol,
Component Component,
ClassComponent
} from './component' } from './component'
import { RawSlots } from './componentSlots' import { RawSlots } from './componentSlots'
import { isReactive, Ref } from '@vue/reactivity' 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 // A block root keeps track of dynamic nodes within the block in the
// `dynamicChildren` array. // `dynamicChildren` array.
export function createBlock( export function createBlock(
type: VNodeTypes, type: VNodeTypes | ClassComponent,
props?: { [key: string]: any } | null, props?: { [key: string]: any } | null,
children?: any, children?: any,
patchFlag?: number, patchFlag?: number,
@ -203,7 +204,7 @@ export function isSameVNodeType(n1: VNode, n2: VNode): boolean {
} }
export function createVNode( export function createVNode(
type: VNodeTypes, type: VNodeTypes | ClassComponent,
props: (Data & VNodeProps) | null = null, props: (Data & VNodeProps) | null = null,
children: unknown = null, children: unknown = null,
patchFlag: number = 0, patchFlag: number = 0,
@ -216,6 +217,11 @@ export function createVNode(
type = Comment type = Comment
} }
// class component normalization.
if (isFunction(type) && '__vccOpts' in type) {
type = type.__vccOpts
}
// class & style normalization. // class & style normalization.
if (props !== null) { if (props !== null) {
// for reactive or proxy objects, we need to clone it to enable mutation. // for reactive or proxy objects, we need to clone it to enable mutation.