-import { createComponent } from '../src/component'
+import { createComponent } from '../src/apiCreateComponent'
import { ref } from '@vue/reactivity'
import { PropType } from '../src/componentProps'
import { h } from '../src/h'
-import {
- ComponentOptions,
- Component,
- ComponentRenderProxy,
- Data,
- ComponentInstance
-} from './component'
+import { Component, Data, ComponentInstance } from './component'
+import { ComponentOptions } from './componentOptions'
+import { ComponentRenderProxy } from './componentProxy'
import { Directive } from './directives'
import { HostNode, RootRenderFunction } from './createRenderer'
import { InjectionKey } from './apiInject'
--- /dev/null
+import {
+ ComputedOptions,
+ MethodOptions,
+ ComponentOptionsWithoutProps,
+ ComponentOptionsWithArrayProps,
+ ComponentOptionsWithProps
+} from './componentOptions'
+import { SetupContext } from './component'
+import { VNodeChild } from './vnode'
+import { ComponentRenderProxy } from './componentProxy'
+import { ExtractPropTypes } from './componentProps'
+import { isFunction } from '@vue/shared'
+
+// overload 1: direct setup function
+// (uses user defined props interface)
+export function createComponent<Props>(
+ setup: (props: Props, ctx: SetupContext) => object | (() => VNodeChild)
+): (props: Props) => any
+
+// overload 2: object format with no props
+// (uses user defined props interface)
+// return type is for Vetur and TSX support
+export function createComponent<
+ Props,
+ RawBindings,
+ D,
+ C extends ComputedOptions = {},
+ M extends MethodOptions = {}
+>(
+ options: ComponentOptionsWithoutProps<Props, RawBindings, D, C, M>
+): {
+ new (): ComponentRenderProxy<Props, RawBindings, D, C, M>
+}
+
+// overload 3: object format with array props declaration
+// props inferred as { [key in PropNames]?: unknown }
+// return type is for Vetur and TSX support
+export function createComponent<
+ PropNames extends string,
+ RawBindings,
+ D,
+ C extends ComputedOptions = {},
+ M extends MethodOptions = {}
+>(
+ options: ComponentOptionsWithArrayProps<PropNames, RawBindings, D, C, M>
+): {
+ new (): ComponentRenderProxy<
+ { [key in PropNames]?: unknown },
+ RawBindings,
+ D,
+ C,
+ M
+ >
+}
+
+// overload 4: object format with object props declaration
+// see `ExtractPropTypes` in ./componentProps.ts
+export function createComponent<
+ PropsOptions,
+ RawBindings,
+ D,
+ C extends ComputedOptions = {},
+ M extends MethodOptions = {}
+>(
+ options: ComponentOptionsWithProps<PropsOptions, RawBindings, D, C, M>
+): {
+ // for Vetur and TSX support
+ new (): ComponentRenderProxy<
+ ExtractPropTypes<PropsOptions>,
+ RawBindings,
+ D,
+ C,
+ M,
+ ExtractPropTypes<PropsOptions, false>
+ >
+}
+
+// implementation, close to no-op
+export function createComponent(options: any) {
+ return isFunction(options) ? { setup: options } : (options as any)
+}
ComponentInstance,
LifecycleHooks,
currentInstance,
- setCurrentInstance,
- ComponentRenderProxy
+ setCurrentInstance
} from './component'
+import { ComponentRenderProxy } from './componentProxy'
import { callWithAsyncErrorHandling, ErrorTypeStrings } from './errorHandling'
import { warn } from './warning'
import { capitalize } from '@vue/shared'
import { VNode, normalizeVNode, VNodeChild, createVNode, Empty } from './vnode'
-import { ReactiveEffect, UnwrapRef, reactive, readonly } from '@vue/reactivity'
-import {
- EMPTY_OBJ,
- isFunction,
- capitalize,
- NOOP,
- isArray,
- isObject
-} from '@vue/shared'
-import { RenderProxyHandlers } from './componentProxy'
-import { ComponentPropsOptions, ExtractPropTypes } from './componentProps'
+import { ReactiveEffect, reactive, readonly } from '@vue/reactivity'
+import { RenderProxyHandlers, ComponentRenderProxy } from './componentProxy'
+import { ComponentPropsOptions } from './componentProps'
import { Slots } from './componentSlots'
import { PatchFlags } from './patchFlags'
import { ShapeFlags } from './shapeFlags'
import { Directive } from './directives'
import {
applyOptions,
- LegacyOptions,
resolveAsset,
- ComputedOptions,
- MethodOptions,
- ExtracComputedReturns
-} from './apiOptions'
+ ComponentOptions
+} from './componentOptions'
+import {
+ EMPTY_OBJ,
+ isFunction,
+ capitalize,
+ NOOP,
+ isArray,
+ isObject
+} from '@vue/shared'
export type Data = { [key: string]: unknown }
-// public properties exposed on the proxy, which is used as the render context
-// in templates (as `this` in the render option)
-export type ComponentRenderProxy<
- P = {},
- B = {},
- D = {},
- C = {},
- M = {},
- PublicProps = P
-> = {
- $data: D
- $props: PublicProps
- $attrs: Data
- $refs: Data
- $slots: Data
- $root: ComponentInstance | null
- $parent: ComponentInstance | null
- $emit: (event: string, ...args: unknown[]) => void
-} & P &
- UnwrapRef<B> &
- D &
- ExtracComputedReturns<C> &
- M
-
-interface ComponentOptionsBase<
- Props,
- RawBindings,
- D,
- C extends ComputedOptions,
- M extends MethodOptions
-> extends LegacyOptions<Props, RawBindings, D, C, M> {
- setup?: (
- this: null,
- props: Props,
- ctx: SetupContext
- ) => RawBindings | (() => VNodeChild) | void
- name?: string
- template?: string
- // Note: we are intentionally using the signature-less `Function` type here
- // since any type with signature will cause the whole inference to fail when
- // the return expression contains reference to `this`.
- // Luckily `render()` doesn't need any arguments nor does it care about return
- // type.
- render?: Function
- components?: Record<string, Component>
- directives?: Record<string, Directive>
-}
-
-export type ComponentOptionsWithoutProps<
- Props = {},
- RawBindings = {},
- D = {},
- C extends ComputedOptions = {},
- M extends MethodOptions = {}
-> = ComponentOptionsBase<Props, RawBindings, D, C, M> & {
- props?: undefined
-} & ThisType<ComponentRenderProxy<Props, RawBindings, D, C, M>>
-
-export type ComponentOptionsWithArrayProps<
- PropNames extends string = string,
- RawBindings = {},
- D = {},
- C extends ComputedOptions = {},
- M extends MethodOptions = {},
- Props = { [key in PropNames]?: unknown }
-> = ComponentOptionsBase<Props, RawBindings, D, C, M> & {
- props: PropNames[]
-} & ThisType<ComponentRenderProxy<Props, RawBindings, D, C, M>>
-
-export type ComponentOptionsWithProps<
- PropsOptions = ComponentPropsOptions,
- RawBindings = {},
- D = {},
- C extends ComputedOptions = {},
- M extends MethodOptions = {},
- Props = ExtractPropTypes<PropsOptions>
-> = ComponentOptionsBase<Props, RawBindings, D, C, M> & {
- props: PropsOptions
-} & ThisType<ComponentRenderProxy<Props, RawBindings, D, C, M>>
-
-export type ComponentOptions =
- | ComponentOptionsWithoutProps
- | ComponentOptionsWithProps
- | ComponentOptionsWithArrayProps
-
export interface FunctionalComponent<P = {}> {
(props: P, ctx: SetupContext): VNodeChild
props?: ComponentPropsOptions<P>
type Emit = ((event: string, ...args: unknown[]) => void)
-interface SetupContext {
+export interface SetupContext {
attrs: Data
slots: Slots
emit: Emit
[LifecycleHooks.ERROR_CAPTURED]: LifecycleHook
}
-// createComponent
-// overload 1: direct setup function
-// (uses user defined props interface)
-export function createComponent<Props>(
- setup: (props: Props, ctx: SetupContext) => object | (() => VNodeChild)
-): (props: Props) => any
-// overload 2: object format with no props
-// (uses user defined props interface)
-// return type is for Vetur and TSX support
-export function createComponent<
- Props,
- RawBindings,
- D,
- C extends ComputedOptions = {},
- M extends MethodOptions = {}
->(
- options: ComponentOptionsWithoutProps<Props, RawBindings, D, C, M>
-): {
- new (): ComponentRenderProxy<Props, RawBindings, D, C, M>
-}
-// overload 3: object format with array props declaration
-// props inferred as { [key in PropNames]?: unknown }
-// return type is for Vetur and TSX support
-export function createComponent<
- PropNames extends string,
- RawBindings,
- D,
- C extends ComputedOptions = {},
- M extends MethodOptions = {}
->(
- options: ComponentOptionsWithArrayProps<PropNames, RawBindings, D, C, M>
-): {
- new (): ComponentRenderProxy<
- { [key in PropNames]?: unknown },
- RawBindings,
- D,
- C,
- M
- >
-}
-// overload 4: object format with object props declaration
-// see `ExtractPropTypes` in ./componentProps.ts
-export function createComponent<
- PropsOptions,
- RawBindings,
- D,
- C extends ComputedOptions = {},
- M extends MethodOptions = {}
->(
- options: ComponentOptionsWithProps<PropsOptions, RawBindings, D, C, M>
-): {
- // for Vetur and TSX support
- new (): ComponentRenderProxy<
- ExtractPropTypes<PropsOptions>,
- RawBindings,
- D,
- C,
- M,
- ExtractPropTypes<PropsOptions, false>
- >
-}
-// implementation, close to no-op
-export function createComponent(options: any) {
- return isFunction(options) ? { setup: options } : (options as any)
-}
-
const emptyAppContext = createAppContext()
export function createComponentInstance(
import {
ComponentInstance,
Data,
- ComponentOptions,
currentRenderingInstance,
currentInstance,
- ComponentRenderProxy
+ Component,
+ SetupContext
} from './component'
import {
isFunction,
} from './apiLifecycle'
import { DebuggerEvent, reactive } from '@vue/reactivity'
import { warn } from './warning'
+import { ComponentPropsOptions, ExtractPropTypes } from './componentProps'
+import { Directive } from './directives'
+import { VNodeChild } from './vnode'
+import { ComponentRenderProxy } from './componentProxy'
+
+interface ComponentOptionsBase<
+ Props,
+ RawBindings,
+ D,
+ C extends ComputedOptions,
+ M extends MethodOptions
+> extends LegacyOptions<Props, RawBindings, D, C, M> {
+ setup?: (
+ this: null,
+ props: Props,
+ ctx: SetupContext
+ ) => RawBindings | (() => VNodeChild) | void
+ name?: string
+ template?: string
+ // Note: we are intentionally using the signature-less `Function` type here
+ // since any type with signature will cause the whole inference to fail when
+ // the return expression contains reference to `this`.
+ // Luckily `render()` doesn't need any arguments nor does it care about return
+ // type.
+ render?: Function
+ components?: Record<string, Component>
+ directives?: Record<string, Directive>
+}
+
+export type ComponentOptionsWithoutProps<
+ Props = {},
+ RawBindings = {},
+ D = {},
+ C extends ComputedOptions = {},
+ M extends MethodOptions = {}
+> = ComponentOptionsBase<Props, RawBindings, D, C, M> & {
+ props?: undefined
+} & ThisType<ComponentRenderProxy<Props, RawBindings, D, C, M>>
+
+export type ComponentOptionsWithArrayProps<
+ PropNames extends string = string,
+ RawBindings = {},
+ D = {},
+ C extends ComputedOptions = {},
+ M extends MethodOptions = {},
+ Props = { [key in PropNames]?: unknown }
+> = ComponentOptionsBase<Props, RawBindings, D, C, M> & {
+ props: PropNames[]
+} & ThisType<ComponentRenderProxy<Props, RawBindings, D, C, M>>
+
+export type ComponentOptionsWithProps<
+ PropsOptions = ComponentPropsOptions,
+ RawBindings = {},
+ D = {},
+ C extends ComputedOptions = {},
+ M extends MethodOptions = {},
+ Props = ExtractPropTypes<PropsOptions>
+> = ComponentOptionsBase<Props, RawBindings, D, C, M> & {
+ props: PropsOptions
+} & ThisType<ComponentRenderProxy<Props, RawBindings, D, C, M>>
+
+export type ComponentOptions =
+ | ComponentOptionsWithoutProps
+ | ComponentOptionsWithProps
+ | ComponentOptionsWithArrayProps
// TODO legacy component definition also supports constructors with .options
type LegacyComponent = ComponentOptions
onCleanup: CleanupRegistrator
) => void
+type ComponentWatchOptions = Record<
+ string,
+ string | WatchHandler | { handler: WatchHandler } & WatchOptions
+>
+
+type ComponentInjectOptions =
+ | string[]
+ | Record<
+ string | symbol,
+ string | symbol | { from: string | symbol; default?: any }
+ >
+
// TODO type inference for these options
export interface LegacyOptions<
Props,
el?: any
// state
+ // Limitation: we cannot expose RawBindings on the `this` context for data
+ // since that leads to some sort of circular inference and breaks ThisType
+ // for the entire component.
data?: D | ((this: ComponentRenderProxy<Props>) => D)
computed?: C
methods?: M
// TODO watch array
- watch?: Record<
- string,
- string | WatchHandler | { handler: WatchHandler } & WatchOptions
- >
+ watch?: ComponentWatchOptions
provide?: Data | Function
- inject?:
- | string[]
- | Record<
- string | symbol,
- string | symbol | { from: string | symbol; default?: any }
- >
+ inject?: ComponentInjectOptions
// composition
mixins?: LegacyComponent[]
-import { ComponentInstance } from './component'
+import { ComponentInstance, Data } from './component'
import { nextTick } from './scheduler'
import { instanceWatch } from './apiWatch'
import { EMPTY_OBJ, hasOwn } from '@vue/shared'
+import { ExtracComputedReturns } from './componentOptions'
+import { UnwrapRef } from '@vue/reactivity'
+
+// public properties exposed on the proxy, which is used as the render context
+// in templates (as `this` in the render option)
+export type ComponentRenderProxy<
+ P = {},
+ B = {},
+ D = {},
+ C = {},
+ M = {},
+ PublicProps = P
+> = {
+ $data: D
+ $props: PublicProps
+ $attrs: Data
+ $refs: Data
+ $slots: Data
+ $root: ComponentInstance | null
+ $parent: ComponentInstance | null
+ $emit: (event: string, ...args: unknown[]) => void
+} & P &
+ UnwrapRef<B> &
+ D &
+ ExtracComputedReturns<C> &
+ M
export const RenderProxyHandlers = {
get(target: ComponentInstance, key: string) {
import { VNode, cloneVNode } from './vnode'
import { extend, isArray, isFunction } from '@vue/shared'
import { warn } from './warning'
-import {
- ComponentInstance,
- currentRenderingInstance,
- ComponentRenderProxy
-} from './component'
+import { ComponentInstance, currentRenderingInstance } from './component'
import { callWithAsyncErrorHandling, ErrorTypes } from './errorHandling'
import { HostNode } from './createRenderer'
-import { resolveAsset } from './apiOptions'
+import { resolveAsset } from './componentOptions'
+import { ComponentRenderProxy } from './componentProxy'
export interface DirectiveBinding {
instance: ComponentRenderProxy | null
import { isObject, isArray } from '@vue/shared'
import { Ref } from '@vue/reactivity'
import { RawSlots } from './componentSlots'
+import { FunctionalComponent } from './component'
import {
- FunctionalComponent,
ComponentOptionsWithoutProps,
ComponentOptionsWithArrayProps,
ComponentOptionsWithProps,
ComponentOptions
-} from './component'
+} from './componentOptions'
import { ExtractPropTypes } from './componentProps'
// `h` is a more user-friendly version of `createVNode` that allows omitting the
// Public API ------------------------------------------------------------------
-export { createComponent } from './component'
+export { createComponent } from './apiCreateComponent'
export { nextTick } from './scheduler'
export * from './apiReactivity'
export * from './apiWatch'