types: avoid duplicate type declarations for renderer closure functions
This commit is contained in:
parent
e0f3c6b352
commit
96605b79a3
@ -2,7 +2,7 @@ import { VNode, normalizeVNode, VNodeChild } from '../vnode'
|
|||||||
import { isFunction, isArray, ShapeFlags } from '@vue/shared'
|
import { isFunction, isArray, ShapeFlags } from '@vue/shared'
|
||||||
import { ComponentInternalInstance, handleSetupResult } from '../component'
|
import { ComponentInternalInstance, handleSetupResult } from '../component'
|
||||||
import { Slots } from '../componentSlots'
|
import { Slots } from '../componentSlots'
|
||||||
import { RendererInternals, MoveType } from '../renderer'
|
import { RendererInternals, MoveType, SetupRenderEffectFn } from '../renderer'
|
||||||
import { queuePostFlushCb, queueJob } from '../scheduler'
|
import { queuePostFlushCb, queueJob } from '../scheduler'
|
||||||
import { updateHOCHostEl } from '../componentRenderUtils'
|
import { updateHOCHostEl } from '../componentRenderUtils'
|
||||||
import { handleError, ErrorCodes } from '../errorHandling'
|
import { handleError, ErrorCodes } from '../errorHandling'
|
||||||
@ -216,14 +216,7 @@ export interface SuspenseBoundary<
|
|||||||
next(): HostNode | null
|
next(): HostNode | null
|
||||||
registerDep(
|
registerDep(
|
||||||
instance: ComponentInternalInstance,
|
instance: ComponentInternalInstance,
|
||||||
setupRenderEffect: (
|
setupRenderEffect: SetupRenderEffectFn<HostNode, HostElement>
|
||||||
instance: ComponentInternalInstance,
|
|
||||||
initialVNode: VNode<HostNode, HostElement>,
|
|
||||||
container: HostElement | null,
|
|
||||||
anchor: HostNode | null,
|
|
||||||
parentSuspense: SuspenseBoundary<HostNode, HostElement> | null,
|
|
||||||
isSVG: boolean
|
|
||||||
) => void
|
|
||||||
): void
|
): void
|
||||||
unmount(
|
unmount(
|
||||||
parentSuspense: SuspenseBoundary<HostNode, HostElement> | null,
|
parentSuspense: SuspenseBoundary<HostNode, HostElement> | null,
|
||||||
|
@ -12,7 +12,7 @@ import { ComponentInternalInstance } from './component'
|
|||||||
import { invokeDirectiveHook } from './directives'
|
import { invokeDirectiveHook } from './directives'
|
||||||
import { warn } from './warning'
|
import { warn } from './warning'
|
||||||
import { PatchFlags, ShapeFlags, isReservedProp, isOn } from '@vue/shared'
|
import { PatchFlags, ShapeFlags, isReservedProp, isOn } from '@vue/shared'
|
||||||
import { RendererOptions } from './renderer'
|
import { RendererOptions, MountComponentFn } from './renderer'
|
||||||
|
|
||||||
export type RootHydrateFunction = (
|
export type RootHydrateFunction = (
|
||||||
vnode: VNode<Node, Element>,
|
vnode: VNode<Node, Element>,
|
||||||
@ -25,7 +25,7 @@ export type RootHydrateFunction = (
|
|||||||
// Hydration also depends on some renderer internal logic which needs to be
|
// Hydration also depends on some renderer internal logic which needs to be
|
||||||
// passed in via arguments.
|
// passed in via arguments.
|
||||||
export function createHydrationFunctions(
|
export function createHydrationFunctions(
|
||||||
mountComponent: any, // TODO
|
mountComponent: MountComponentFn<Node, Element>,
|
||||||
patchProp: RendererOptions['patchProp']
|
patchProp: RendererOptions['patchProp']
|
||||||
) {
|
) {
|
||||||
const hydrate: RootHydrateFunction = (vnode, container) => {
|
const hydrate: RootHydrateFunction = (vnode, container) => {
|
||||||
@ -68,6 +68,9 @@ export function createHydrationFunctions(
|
|||||||
if (shapeFlag & ShapeFlags.ELEMENT) {
|
if (shapeFlag & ShapeFlags.ELEMENT) {
|
||||||
return hydrateElement(node as Element, vnode, parentComponent)
|
return hydrateElement(node as Element, vnode, parentComponent)
|
||||||
} else if (shapeFlag & ShapeFlags.COMPONENT) {
|
} else if (shapeFlag & ShapeFlags.COMPONENT) {
|
||||||
|
// when setting up the render effect, if the initial vnode already
|
||||||
|
// has .el set, the component will perform hydration instead of mount
|
||||||
|
// on its sub-tree.
|
||||||
mountComponent(vnode, null, null, parentComponent, null, false)
|
mountComponent(vnode, null, null, parentComponent, null, false)
|
||||||
const subTree = vnode.component!.subTree
|
const subTree = vnode.component!.subTree
|
||||||
return (subTree.anchor || subTree.el).nextSibling
|
return (subTree.anchor || subTree.el).nextSibling
|
||||||
|
@ -90,11 +90,7 @@ export interface RendererOptions<HostNode = any, HostElement = any> {
|
|||||||
prevChildren?: VNode<HostNode, HostElement>[],
|
prevChildren?: VNode<HostNode, HostElement>[],
|
||||||
parentComponent?: ComponentInternalInstance | null,
|
parentComponent?: ComponentInternalInstance | null,
|
||||||
parentSuspense?: SuspenseBoundary<HostNode, HostElement> | null,
|
parentSuspense?: SuspenseBoundary<HostNode, HostElement> | null,
|
||||||
unmountChildren?: (
|
unmountChildren?: UnmountChildrenFn<HostNode, HostElement>
|
||||||
children: VNode<HostNode, HostElement>[],
|
|
||||||
parentComponent: ComponentInternalInstance | null,
|
|
||||||
parentSuspense: SuspenseBoundary<HostNode, HostElement> | null
|
|
||||||
) => void
|
|
||||||
): void
|
): void
|
||||||
insert(el: HostNode, parent: HostElement, anchor?: HostNode | null): void
|
insert(el: HostNode, parent: HostElement, anchor?: HostNode | null): void
|
||||||
remove(el: HostNode): void
|
remove(el: HostNode): void
|
||||||
@ -116,6 +112,75 @@ export interface RendererOptions<HostNode = any, HostElement = any> {
|
|||||||
): HostElement
|
): HostElement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// An object exposing the internals of a renderer, passed to tree-shakeable
|
||||||
|
// features so that they can be decoupled from this file.
|
||||||
|
export interface RendererInternals<HostNode = any, HostElement = any> {
|
||||||
|
patch: PatchFn<HostNode, HostElement>
|
||||||
|
unmount: UnmountFn<HostNode, HostElement>
|
||||||
|
move: MoveFn<HostNode, HostElement>
|
||||||
|
next: NextFn<HostNode, HostElement>
|
||||||
|
options: RendererOptions<HostNode, HostElement>
|
||||||
|
}
|
||||||
|
|
||||||
|
// These functions are created inside a closure and therefore there types cannot
|
||||||
|
// be directly exported. In order to avoid maintaining function signatures in
|
||||||
|
// two places, we declare them once here and use them inside the closure.
|
||||||
|
type PatchFn<HostNode, HostElement> = (
|
||||||
|
n1: VNode<HostNode, HostElement> | null, // null means this is a mount
|
||||||
|
n2: VNode<HostNode, HostElement>,
|
||||||
|
container: HostElement,
|
||||||
|
anchor?: HostNode | null,
|
||||||
|
parentComponent?: ComponentInternalInstance | null,
|
||||||
|
parentSuspense?: SuspenseBoundary<HostNode, HostElement> | null,
|
||||||
|
isSVG?: boolean,
|
||||||
|
optimized?: boolean
|
||||||
|
) => void
|
||||||
|
|
||||||
|
type UnmountFn<HostNode, HostElement> = (
|
||||||
|
vnode: VNode<HostNode, HostElement>,
|
||||||
|
parentComponent: ComponentInternalInstance | null,
|
||||||
|
parentSuspense: SuspenseBoundary<HostNode, HostElement> | null,
|
||||||
|
doRemove?: boolean
|
||||||
|
) => void
|
||||||
|
|
||||||
|
type MoveFn<HostNode, HostElement> = (
|
||||||
|
vnode: VNode<HostNode, HostElement>,
|
||||||
|
container: HostElement,
|
||||||
|
anchor: HostNode | null,
|
||||||
|
type: MoveType,
|
||||||
|
parentSuspense?: SuspenseBoundary<HostNode, HostElement> | null
|
||||||
|
) => void
|
||||||
|
|
||||||
|
type NextFn<HostNode, HostElement> = (
|
||||||
|
vnode: VNode<HostNode, HostElement>
|
||||||
|
) => HostNode | null
|
||||||
|
|
||||||
|
type UnmountChildrenFn<HostNode, HostElement> = (
|
||||||
|
children: VNode<HostNode, HostElement>[],
|
||||||
|
parentComponent: ComponentInternalInstance | null,
|
||||||
|
parentSuspense: SuspenseBoundary<HostNode, HostElement> | null,
|
||||||
|
doRemove?: boolean,
|
||||||
|
start?: number
|
||||||
|
) => void
|
||||||
|
|
||||||
|
export type MountComponentFn<HostNode, HostElement> = (
|
||||||
|
initialVNode: VNode<HostNode, HostElement>,
|
||||||
|
container: HostElement | null, // only null during hydration
|
||||||
|
anchor: HostNode | null,
|
||||||
|
parentComponent: ComponentInternalInstance | null,
|
||||||
|
parentSuspense: SuspenseBoundary<HostNode, HostElement> | null,
|
||||||
|
isSVG: boolean
|
||||||
|
) => void
|
||||||
|
|
||||||
|
export type SetupRenderEffectFn<HostNode, HostElement> = (
|
||||||
|
instance: ComponentInternalInstance,
|
||||||
|
initialVNode: VNode<HostNode, HostElement>,
|
||||||
|
container: HostElement | null, // only null during hydration
|
||||||
|
anchor: HostNode | null,
|
||||||
|
parentSuspense: SuspenseBoundary<HostNode, HostElement> | null,
|
||||||
|
isSVG: boolean
|
||||||
|
) => void
|
||||||
|
|
||||||
export const enum MoveType {
|
export const enum MoveType {
|
||||||
ENTER,
|
ENTER,
|
||||||
LEAVE,
|
LEAVE,
|
||||||
@ -223,15 +288,17 @@ function baseCreateRenderer<
|
|||||||
insertStaticContent: hostInsertStaticContent
|
insertStaticContent: hostInsertStaticContent
|
||||||
} = options
|
} = options
|
||||||
|
|
||||||
const patch = (
|
// Note: functions inside this closure should use `const xxx = () => {}`
|
||||||
n1: HostVNode | null, // null means this is a mount
|
// style in order to prevent being inlined by minifiers.
|
||||||
n2: HostVNode,
|
const patch: PatchFn<HostNode, HostElement> = (
|
||||||
container: HostElement,
|
n1,
|
||||||
anchor: HostNode | null = null,
|
n2,
|
||||||
parentComponent: ComponentInternalInstance | null = null,
|
container,
|
||||||
parentSuspense: HostSuspenseBoundary | null = null,
|
anchor = null,
|
||||||
isSVG: boolean = false,
|
parentComponent = null,
|
||||||
optimized: boolean = false
|
parentSuspense = null,
|
||||||
|
isSVG = false,
|
||||||
|
optimized = false
|
||||||
) => {
|
) => {
|
||||||
// patching & not same type, unmount old tree
|
// patching & not same type, unmount old tree
|
||||||
if (n1 != null && !isSameVNodeType(n1, n2)) {
|
if (n1 != null && !isSameVNodeType(n1, n2)) {
|
||||||
@ -984,13 +1051,13 @@ function baseCreateRenderer<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mountComponent = (
|
const mountComponent: MountComponentFn<HostNode, HostElement> = (
|
||||||
initialVNode: HostVNode,
|
initialVNode,
|
||||||
container: HostElement | null, // only null during hydration
|
container, // only null during hydration
|
||||||
anchor: HostNode | null,
|
anchor,
|
||||||
parentComponent: ComponentInternalInstance | null,
|
parentComponent,
|
||||||
parentSuspense: HostSuspenseBoundary | null,
|
parentSuspense,
|
||||||
isSVG: boolean
|
isSVG
|
||||||
) => {
|
) => {
|
||||||
const instance: ComponentInternalInstance = (initialVNode.component = createComponentInstance(
|
const instance: ComponentInternalInstance = (initialVNode.component = createComponentInstance(
|
||||||
initialVNode,
|
initialVNode,
|
||||||
@ -1046,13 +1113,13 @@ function baseCreateRenderer<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const setupRenderEffect = (
|
const setupRenderEffect: SetupRenderEffectFn<HostNode, HostElement> = (
|
||||||
instance: ComponentInternalInstance,
|
instance,
|
||||||
initialVNode: HostVNode,
|
initialVNode,
|
||||||
container: HostElement | null, // only null during hydration
|
container,
|
||||||
anchor: HostNode | null,
|
anchor,
|
||||||
parentSuspense: HostSuspenseBoundary | null,
|
parentSuspense,
|
||||||
isSVG: boolean
|
isSVG
|
||||||
) => {
|
) => {
|
||||||
// create reactive effect for rendering
|
// create reactive effect for rendering
|
||||||
instance.update = effect(function componentEffect() {
|
instance.update = effect(function componentEffect() {
|
||||||
@ -1545,12 +1612,12 @@ function baseCreateRenderer<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const move = (
|
const move: MoveFn<HostNode, HostElement> = (
|
||||||
vnode: HostVNode,
|
vnode,
|
||||||
container: HostElement,
|
container,
|
||||||
anchor: HostNode | null,
|
anchor,
|
||||||
type: MoveType,
|
type,
|
||||||
parentSuspense: HostSuspenseBoundary | null = null
|
parentSuspense = null
|
||||||
) => {
|
) => {
|
||||||
if (vnode.shapeFlag & ShapeFlags.COMPONENT) {
|
if (vnode.shapeFlag & ShapeFlags.COMPONENT) {
|
||||||
move(vnode.component!.subTree, container, anchor, type)
|
move(vnode.component!.subTree, container, anchor, type)
|
||||||
@ -1600,11 +1667,11 @@ function baseCreateRenderer<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const unmount = (
|
const unmount: UnmountFn<HostNode, HostElement> = (
|
||||||
vnode: HostVNode,
|
vnode,
|
||||||
parentComponent: ComponentInternalInstance | null,
|
parentComponent,
|
||||||
parentSuspense: HostSuspenseBoundary | null,
|
parentSuspense,
|
||||||
doRemove?: boolean
|
doRemove = false
|
||||||
) => {
|
) => {
|
||||||
const { props, ref, children, dynamicChildren, shapeFlag } = vnode
|
const { props, ref, children, dynamicChildren, shapeFlag } = vnode
|
||||||
|
|
||||||
@ -1755,19 +1822,19 @@ function baseCreateRenderer<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const unmountChildren = (
|
const unmountChildren: UnmountChildrenFn<HostNode, HostElement> = (
|
||||||
children: HostVNode[],
|
children,
|
||||||
parentComponent: ComponentInternalInstance | null,
|
parentComponent,
|
||||||
parentSuspense: HostSuspenseBoundary | null,
|
parentSuspense,
|
||||||
doRemove?: boolean,
|
doRemove = false,
|
||||||
start: number = 0
|
start = 0
|
||||||
) => {
|
) => {
|
||||||
for (let i = start; i < children.length; i++) {
|
for (let i = start; i < children.length; i++) {
|
||||||
unmount(children[i], parentComponent, parentSuspense, doRemove)
|
unmount(children[i], parentComponent, parentSuspense, doRemove)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getNextHostNode = (vnode: HostVNode): HostNode | null => {
|
const getNextHostNode: NextFn<HostNode, HostElement> = vnode => {
|
||||||
if (vnode.shapeFlag & ShapeFlags.COMPONENT) {
|
if (vnode.shapeFlag & ShapeFlags.COMPONENT) {
|
||||||
return getNextHostNode(vnode.component!.subTree)
|
return getNextHostNode(vnode.component!.subTree)
|
||||||
}
|
}
|
||||||
@ -1842,7 +1909,10 @@ function baseCreateRenderer<
|
|||||||
let hydrate: ReturnType<typeof createHydrationFunctions>[0] | undefined
|
let hydrate: ReturnType<typeof createHydrationFunctions>[0] | undefined
|
||||||
let hydrateNode: ReturnType<typeof createHydrationFunctions>[1] | undefined
|
let hydrateNode: ReturnType<typeof createHydrationFunctions>[1] | undefined
|
||||||
if (createHydrationFns) {
|
if (createHydrationFns) {
|
||||||
;[hydrate, hydrateNode] = createHydrationFns(mountComponent, hostPatchProp)
|
;[hydrate, hydrateNode] = createHydrationFns(
|
||||||
|
mountComponent as MountComponentFn<Node, Element>,
|
||||||
|
hostPatchProp
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -1852,36 +1922,6 @@ function baseCreateRenderer<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// An object exposing the internals of a renderer, passed to tree-shakeable
|
|
||||||
// features so that they can be decoupled from this file.
|
|
||||||
export interface RendererInternals<HostNode = any, HostElement = any> {
|
|
||||||
patch: (
|
|
||||||
n1: VNode<HostNode, HostElement> | null, // null means this is a mount
|
|
||||||
n2: VNode<HostNode, HostElement>,
|
|
||||||
container: HostElement,
|
|
||||||
anchor?: HostNode | null,
|
|
||||||
parentComponent?: ComponentInternalInstance | null,
|
|
||||||
parentSuspense?: SuspenseBoundary<HostNode, HostElement> | null,
|
|
||||||
isSVG?: boolean,
|
|
||||||
optimized?: boolean
|
|
||||||
) => void
|
|
||||||
unmount: (
|
|
||||||
vnode: VNode<HostNode, HostElement>,
|
|
||||||
parentComponent: ComponentInternalInstance | null,
|
|
||||||
parentSuspense: SuspenseBoundary<HostNode, HostElement> | null,
|
|
||||||
doRemove?: boolean
|
|
||||||
) => void
|
|
||||||
move: (
|
|
||||||
vnode: VNode<HostNode, HostElement>,
|
|
||||||
container: HostElement,
|
|
||||||
anchor: HostNode | null,
|
|
||||||
type: MoveType,
|
|
||||||
parentSuspense?: SuspenseBoundary<HostNode, HostElement> | null
|
|
||||||
) => void
|
|
||||||
next: (vnode: VNode<HostNode, HostElement>) => HostNode | null
|
|
||||||
options: RendererOptions<HostNode, HostElement>
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://en.wikipedia.org/wiki/Longest_increasing_subsequence
|
// https://en.wikipedia.org/wiki/Longest_increasing_subsequence
|
||||||
function getSequence(arr: number[]): number[] {
|
function getSequence(arr: number[]): number[] {
|
||||||
const p = arr.slice()
|
const p = arr.slice()
|
||||||
|
Loading…
Reference in New Issue
Block a user