feat(ssr): support portal hydration

This commit is contained in:
Evan You 2020-02-14 21:04:08 -05:00
parent 688ad92391
commit 70dc3e3ae7

View File

@ -11,7 +11,13 @@ import { queuePostFlushCb, flushPostFlushCbs } from './scheduler'
import { ComponentInternalInstance } from './component' 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,
isString
} from '@vue/shared'
import { RendererOptions, MountComponentFn } from './renderer' import { RendererOptions, MountComponentFn } from './renderer'
export type RootHydrateFunction = ( export type RootHydrateFunction = (
@ -38,8 +44,6 @@ export function createHydrationFunctions(
} }
// TODO handle mismatches // TODO handle mismatches
// TODO SVG
// TODO Suspense
const hydrateNode = ( const hydrateNode = (
node: Node, node: Node,
vnode: VNode, vnode: VNode,
@ -62,8 +66,8 @@ export function createHydrationFunctions(
// back anchor as expected. // back anchor as expected.
return anchor.nextSibling return anchor.nextSibling
case Portal: case Portal:
// TODO hydratePortal(vnode, parentComponent)
break return node.nextSibling
default: default:
if (shapeFlag & ShapeFlags.ELEMENT) { if (shapeFlag & ShapeFlags.ELEMENT) {
return hydrateElement(node as Element, vnode, parentComponent) return hydrateElement(node as Element, vnode, parentComponent)
@ -75,7 +79,7 @@ export function createHydrationFunctions(
const subTree = vnode.component!.subTree const subTree = vnode.component!.subTree
return (subTree.anchor || subTree.el).nextSibling return (subTree.anchor || subTree.el).nextSibling
} else if (__FEATURE_SUSPENSE__ && shapeFlag & ShapeFlags.SUSPENSE) { } else if (__FEATURE_SUSPENSE__ && shapeFlag & ShapeFlags.SUSPENSE) {
// TODO // TODO Suspense
} else if (__DEV__) { } else if (__DEV__) {
warn('Invalid HostVNode type:', type, `(${typeof type})`) warn('Invalid HostVNode type:', type, `(${typeof type})`)
} }
@ -147,5 +151,22 @@ export function createHydrationFunctions(
return node return node
} }
const hydratePortal = (
vnode: VNode,
parentComponent: ComponentInternalInstance | null
) => {
const targetSelector = vnode.props && vnode.props.target
const target = (vnode.target = isString(targetSelector)
? document.querySelector(targetSelector)
: targetSelector)
if (target != null && vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
hydrateChildren(
target.firstChild,
vnode.children as VNode[],
parentComponent
)
}
}
return [hydrate, hydrateNode] as const return [hydrate, hydrateNode] as const
} }