]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
types: avoid duplicate type declarations for renderer closure functions
authorEvan You <yyx990803@gmail.com>
Fri, 14 Feb 2020 21:25:41 +0000 (16:25 -0500)
committerEvan You <yyx990803@gmail.com>
Fri, 14 Feb 2020 21:25:41 +0000 (16:25 -0500)
packages/runtime-core/src/components/Suspense.ts
packages/runtime-core/src/hydration.ts
packages/runtime-core/src/renderer.ts

index 211e5f30a00f4d20ed8b49fd7fda810fc7ff0ff6..c8f7d5abcb3d4e5c8bbcdce7f915bcd8c3c8a36e 100644 (file)
@@ -2,7 +2,7 @@ import { VNode, normalizeVNode, VNodeChild } from '../vnode'
 import { isFunction, isArray, ShapeFlags } from '@vue/shared'
 import { ComponentInternalInstance, handleSetupResult } from '../component'
 import { Slots } from '../componentSlots'
-import { RendererInternals, MoveType } from '../renderer'
+import { RendererInternals, MoveType, SetupRenderEffectFn } from '../renderer'
 import { queuePostFlushCb, queueJob } from '../scheduler'
 import { updateHOCHostEl } from '../componentRenderUtils'
 import { handleError, ErrorCodes } from '../errorHandling'
@@ -216,14 +216,7 @@ export interface SuspenseBoundary<
   next(): HostNode | null
   registerDep(
     instance: ComponentInternalInstance,
-    setupRenderEffect: (
-      instance: ComponentInternalInstance,
-      initialVNode: VNode<HostNode, HostElement>,
-      container: HostElement | null,
-      anchor: HostNode | null,
-      parentSuspense: SuspenseBoundary<HostNode, HostElement> | null,
-      isSVG: boolean
-    ) => void
+    setupRenderEffect: SetupRenderEffectFn<HostNode, HostElement>
   ): void
   unmount(
     parentSuspense: SuspenseBoundary<HostNode, HostElement> | null,
index e33b754875690cb3c040eacd405298d706fc3b90..bb9b80af7f4642e9123a6c34cb84f0e68943a0df 100644 (file)
@@ -12,7 +12,7 @@ import { ComponentInternalInstance } from './component'
 import { invokeDirectiveHook } from './directives'
 import { warn } from './warning'
 import { PatchFlags, ShapeFlags, isReservedProp, isOn } from '@vue/shared'
-import { RendererOptions } from './renderer'
+import { RendererOptions, MountComponentFn } from './renderer'
 
 export type RootHydrateFunction = (
   vnode: VNode<Node, Element>,
@@ -25,7 +25,7 @@ export type RootHydrateFunction = (
 // Hydration also depends on some renderer internal logic which needs to be
 // passed in via arguments.
 export function createHydrationFunctions(
-  mountComponent: any, // TODO
+  mountComponent: MountComponentFn<Node, Element>,
   patchProp: RendererOptions['patchProp']
 ) {
   const hydrate: RootHydrateFunction = (vnode, container) => {
@@ -68,6 +68,9 @@ export function createHydrationFunctions(
         if (shapeFlag & ShapeFlags.ELEMENT) {
           return hydrateElement(node as Element, vnode, parentComponent)
         } 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)
           const subTree = vnode.component!.subTree
           return (subTree.anchor || subTree.el).nextSibling
index a798178ad46d4d68f7e24a9c0d9fc1391a1d5949..dce719fa26062a34d10e2aa2714c9f9e7170f489 100644 (file)
@@ -90,11 +90,7 @@ export interface RendererOptions<HostNode = any, HostElement = any> {
     prevChildren?: VNode<HostNode, HostElement>[],
     parentComponent?: ComponentInternalInstance | null,
     parentSuspense?: SuspenseBoundary<HostNode, HostElement> | null,
-    unmountChildren?: (
-      children: VNode<HostNode, HostElement>[],
-      parentComponent: ComponentInternalInstance | null,
-      parentSuspense: SuspenseBoundary<HostNode, HostElement> | null
-    ) => void
+    unmountChildren?: UnmountChildrenFn<HostNode, HostElement>
   ): void
   insert(el: HostNode, parent: HostElement, anchor?: HostNode | null): void
   remove(el: HostNode): void
@@ -116,6 +112,75 @@ export interface RendererOptions<HostNode = any, HostElement = any> {
   ): 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 {
   ENTER,
   LEAVE,
@@ -223,15 +288,17 @@ function baseCreateRenderer<
     insertStaticContent: hostInsertStaticContent
   } = options
 
-  const patch = (
-    n1: HostVNode | null, // null means this is a mount
-    n2: HostVNode,
-    container: HostElement,
-    anchor: HostNode | null = null,
-    parentComponent: ComponentInternalInstance | null = null,
-    parentSuspense: HostSuspenseBoundary | null = null,
-    isSVG: boolean = false,
-    optimized: boolean = false
+  // Note: functions inside this closure should use `const xxx = () => {}`
+  // style in order to prevent being inlined by minifiers.
+  const patch: PatchFn<HostNode, HostElement> = (
+    n1,
+    n2,
+    container,
+    anchor = null,
+    parentComponent = null,
+    parentSuspense = null,
+    isSVG = false,
+    optimized = false
   ) => {
     // patching & not same type, unmount old tree
     if (n1 != null && !isSameVNodeType(n1, n2)) {
@@ -984,13 +1051,13 @@ function baseCreateRenderer<
     }
   }
 
-  const mountComponent = (
-    initialVNode: HostVNode,
-    container: HostElement | null, // only null during hydration
-    anchor: HostNode | null,
-    parentComponent: ComponentInternalInstance | null,
-    parentSuspense: HostSuspenseBoundary | null,
-    isSVG: boolean
+  const mountComponent: MountComponentFn<HostNode, HostElement> = (
+    initialVNode,
+    container, // only null during hydration
+    anchor,
+    parentComponent,
+    parentSuspense,
+    isSVG
   ) => {
     const instance: ComponentInternalInstance = (initialVNode.component = createComponentInstance(
       initialVNode,
@@ -1046,13 +1113,13 @@ function baseCreateRenderer<
     }
   }
 
-  const setupRenderEffect = (
-    instance: ComponentInternalInstance,
-    initialVNode: HostVNode,
-    container: HostElement | null, // only null during hydration
-    anchor: HostNode | null,
-    parentSuspense: HostSuspenseBoundary | null,
-    isSVG: boolean
+  const setupRenderEffect: SetupRenderEffectFn<HostNode, HostElement> = (
+    instance,
+    initialVNode,
+    container,
+    anchor,
+    parentSuspense,
+    isSVG
   ) => {
     // create reactive effect for rendering
     instance.update = effect(function componentEffect() {
@@ -1545,12 +1612,12 @@ function baseCreateRenderer<
     }
   }
 
-  const move = (
-    vnode: HostVNode,
-    container: HostElement,
-    anchor: HostNode | null,
-    type: MoveType,
-    parentSuspense: HostSuspenseBoundary | null = null
+  const move: MoveFn<HostNode, HostElement> = (
+    vnode,
+    container,
+    anchor,
+    type,
+    parentSuspense = null
   ) => {
     if (vnode.shapeFlag & ShapeFlags.COMPONENT) {
       move(vnode.component!.subTree, container, anchor, type)
@@ -1600,11 +1667,11 @@ function baseCreateRenderer<
     }
   }
 
-  const unmount = (
-    vnode: HostVNode,
-    parentComponent: ComponentInternalInstance | null,
-    parentSuspense: HostSuspenseBoundary | null,
-    doRemove?: boolean
+  const unmount: UnmountFn<HostNode, HostElement> = (
+    vnode,
+    parentComponent,
+    parentSuspense,
+    doRemove = false
   ) => {
     const { props, ref, children, dynamicChildren, shapeFlag } = vnode
 
@@ -1755,19 +1822,19 @@ function baseCreateRenderer<
     }
   }
 
-  const unmountChildren = (
-    children: HostVNode[],
-    parentComponent: ComponentInternalInstance | null,
-    parentSuspense: HostSuspenseBoundary | null,
-    doRemove?: boolean,
-    start: number = 0
+  const unmountChildren: UnmountChildrenFn<HostNode, HostElement> = (
+    children,
+    parentComponent,
+    parentSuspense,
+    doRemove = false,
+    start = 0
   ) => {
     for (let i = start; i < children.length; i++) {
       unmount(children[i], parentComponent, parentSuspense, doRemove)
     }
   }
 
-  const getNextHostNode = (vnode: HostVNode): HostNode | null => {
+  const getNextHostNode: NextFn<HostNode, HostElement> = vnode => {
     if (vnode.shapeFlag & ShapeFlags.COMPONENT) {
       return getNextHostNode(vnode.component!.subTree)
     }
@@ -1842,7 +1909,10 @@ function baseCreateRenderer<
   let hydrate: ReturnType<typeof createHydrationFunctions>[0] | undefined
   let hydrateNode: ReturnType<typeof createHydrationFunctions>[1] | undefined
   if (createHydrationFns) {
-    ;[hydrate, hydrateNode] = createHydrationFns(mountComponent, hostPatchProp)
+    ;[hydrate, hydrateNode] = createHydrationFns(
+      mountComponent as MountComponentFn<Node, Element>,
+      hostPatchProp
+    )
   }
 
   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
 function getSequence(arr: number[]): number[] {
   const p = arr.slice()