| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- import {
- VNode,
- VNodeProps,
- createVNode,
- VNodeArrayChildren,
- Fragment,
- isVNode
- } from './vnode'
- import { Portal, PortalProps } from './components/Portal'
- import { Suspense, SuspenseProps } from './components/Suspense'
- import { isObject, isArray } from '@vue/shared'
- import { RawSlots } from './componentSlots'
- import { FunctionalComponent } from './component'
- import {
- ComponentOptionsWithoutProps,
- ComponentOptionsWithArrayProps,
- ComponentOptionsWithObjectProps,
- ComponentOptions
- } from './apiOptions'
- import { ExtractPropTypes } from './componentProps'
- // `h` is a more user-friendly version of `createVNode` that allows omitting the
- // props when possible. It is intended for manually written render functions.
- // Compiler-generated code uses `createVNode` because
- // 1. it is monomorphic and avoids the extra call overhead
- // 2. it allows specifying patchFlags for optimization
- /*
- // type only
- h('div')
- // type + props
- h('div', {})
- // type + omit props + children
- // Omit props does NOT support named slots
- h('div', []) // array
- h('div', 'foo') // text
- h('div', h('br')) // vnode
- h(Component, () => {}) // default slot
- // type + props + children
- h('div', {}, []) // array
- h('div', {}, 'foo') // text
- h('div', {}, h('br')) // vnode
- h(Component, {}, () => {}) // default slot
- h(Component, {}, {}) // named slots
- // named slots without props requires explicit `null` to avoid ambiguity
- h(Component, null, {})
- **/
- type RawProps = VNodeProps & {
- // used to differ from a single VNode object as children
- _isVNode?: never
- // used to differ from Array children
- [Symbol.iterator]?: never
- }
- type RawChildren =
- | string
- | number
- | boolean
- | VNode
- | VNodeArrayChildren
- | (() => any)
- // fake constructor type returned from `defineComponent`
- interface Constructor<P = any> {
- __isFragment?: never
- __isPortal?: never
- __isSuspense?: never
- new (): { $props: P }
- }
- // The following is a series of overloads for providing props validation of
- // manually written render functions.
- // element
- export function h(type: string, children?: RawChildren): VNode
- export function h(
- type: string,
- props?: RawProps | null,
- children?: RawChildren
- ): VNode
- // fragment
- export function h(type: typeof Fragment, children?: VNodeArrayChildren): VNode
- export function h(
- type: typeof Fragment,
- props?: RawProps | null,
- children?: VNodeArrayChildren
- ): VNode
- // portal (target prop is required)
- export function h(
- type: typeof Portal,
- props: RawProps & PortalProps,
- children: RawChildren
- ): VNode
- // suspense
- export function h(type: typeof Suspense, children?: RawChildren): VNode
- export function h(
- type: typeof Suspense,
- props?: (RawProps & SuspenseProps) | null,
- children?: RawChildren | RawSlots
- ): VNode
- // functional component
- export function h(type: FunctionalComponent, children?: RawChildren): VNode
- export function h<P>(
- type: FunctionalComponent<P>,
- props?: (RawProps & P) | ({} extends P ? null : never),
- children?: RawChildren | RawSlots
- ): VNode
- // stateful component
- export function h(type: ComponentOptions, children?: RawChildren): VNode
- export function h(
- type: ComponentOptionsWithoutProps | ComponentOptionsWithArrayProps,
- props?: RawProps | null,
- children?: RawChildren | RawSlots
- ): VNode
- export function h<O>(
- type: ComponentOptionsWithObjectProps<O>,
- props?:
- | (RawProps & ExtractPropTypes<O>)
- | ({} extends ExtractPropTypes<O> ? null : never),
- children?: RawChildren | RawSlots
- ): VNode
- // fake constructor type returned by `defineComponent` or class component
- export function h(type: Constructor, children?: RawChildren): VNode
- export function h<P>(
- type: Constructor<P>,
- props?: (RawProps & P) | ({} extends P ? null : never),
- children?: RawChildren | RawSlots
- ): VNode
- // Actual implementation
- export function h(type: any, propsOrChildren?: any, children?: any): VNode {
- if (arguments.length === 2) {
- if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
- // single vnode without props
- if (isVNode(propsOrChildren)) {
- return createVNode(type, null, [propsOrChildren])
- }
- // props without children
- return createVNode(type, propsOrChildren)
- } else {
- // omit props
- return createVNode(type, null, propsOrChildren)
- }
- } else {
- if (isVNode(children)) {
- children = [children]
- }
- return createVNode(type, propsOrChildren, children)
- }
- }
|