feat: add hook for transforming h's arguments (#851)

Note: this is for internal use (e.g. `@vue/test-utils`) only
This commit is contained in:
Jessica Sachs
2020-03-19 10:54:03 -04:00
committed by GitHub
parent d4aaa216db
commit b7d1e0fa2f
2 changed files with 99 additions and 17 deletions

View File

@@ -18,6 +18,7 @@ import {
ComponentOptions
} from './apiOptions'
import { ExtractPropTypes } from './componentProps'
import { currentRenderingInstance } from './componentRenderUtils'
// `h` is a more user-friendly version of `createVNode` that allows omitting the
// props when possible. It is intended for manually written render functions.
@@ -77,52 +78,52 @@ interface Constructor<P = any> {
// manually written render functions.
// element
export function h(type: string, children?: RawChildren): VNode
export function h(
function _h(type: string, children?: RawChildren): VNode
function _h(
type: string,
props?: RawProps | null,
children?: RawChildren
): VNode
// fragment
export function h(type: typeof Fragment, children?: VNodeArrayChildren): VNode
export function h(
function _h(type: typeof Fragment, children?: VNodeArrayChildren): VNode
function _h(
type: typeof Fragment,
props?: RawProps | null,
children?: VNodeArrayChildren
): VNode
// portal (target prop is required)
export function h(
function _h(
type: typeof Portal,
props: RawProps & PortalProps,
children: RawChildren
): VNode
// suspense
export function h(type: typeof Suspense, children?: RawChildren): VNode
export function h(
function _h(type: typeof Suspense, children?: RawChildren): VNode
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>(
function _h(type: FunctionalComponent, children?: RawChildren): VNode
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(
function _h(type: ComponentOptions, children?: RawChildren): VNode
function _h(
type: ComponentOptionsWithoutProps | ComponentOptionsWithArrayProps,
props?: RawProps | null,
children?: RawChildren | RawSlots
): VNode
export function h<O>(
function _h<O>(
type: ComponentOptionsWithObjectProps<O>,
props?:
| (RawProps & ExtractPropTypes<O>)
@@ -131,15 +132,15 @@ export function h<O>(
): VNode
// fake constructor type returned by `defineComponent` or class component
export function h(type: Constructor, children?: RawChildren): VNode
export function h<P>(
function _h(type: Constructor, children?: RawChildren): VNode
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 {
function _h(type: any, propsOrChildren?: any, children?: any): VNode {
if (arguments.length === 2) {
if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
// single vnode without props
@@ -159,3 +160,24 @@ export function h(type: any, propsOrChildren?: any, children?: any): VNode {
return createVNode(type, propsOrChildren, children)
}
}
export const h: typeof _h = __DEV__ ? (applyTransformedH as typeof _h) : _h
let argsTransformer: Function | undefined
// This is used to hook into the h function and transform its arguments
// Useful for re-implementing behavior that was previously done with createElement in Vue 2
function applyTransformedH(...args: unknown[]): VNode {
if (argsTransformer) {
args = argsTransformer(args, currentRenderingInstance)
}
return _h(...(args as Parameters<typeof _h>))
}
export function transformHArgs(transformer: Function): void {
argsTransformer = transformer
}
export function resetTransformHArgs(): void {
argsTransformer = undefined
}