From: Evan You Date: Sat, 15 Feb 2020 02:04:08 +0000 (-0500) Subject: feat(ssr): support portal hydration X-Git-Tag: v3.0.0-alpha.5~27 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=70dc3e3ae74f08d53243e6f078794c16f359e272;p=thirdparty%2Fvuejs%2Fcore.git feat(ssr): support portal hydration --- diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts index bb9b80af7f..2a9e0b1650 100644 --- a/packages/runtime-core/src/hydration.ts +++ b/packages/runtime-core/src/hydration.ts @@ -11,7 +11,13 @@ import { queuePostFlushCb, flushPostFlushCbs } from './scheduler' import { ComponentInternalInstance } from './component' import { invokeDirectiveHook } from './directives' 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' export type RootHydrateFunction = ( @@ -38,8 +44,6 @@ export function createHydrationFunctions( } // TODO handle mismatches - // TODO SVG - // TODO Suspense const hydrateNode = ( node: Node, vnode: VNode, @@ -62,8 +66,8 @@ export function createHydrationFunctions( // back anchor as expected. return anchor.nextSibling case Portal: - // TODO - break + hydratePortal(vnode, parentComponent) + return node.nextSibling default: if (shapeFlag & ShapeFlags.ELEMENT) { return hydrateElement(node as Element, vnode, parentComponent) @@ -75,7 +79,7 @@ export function createHydrationFunctions( const subTree = vnode.component!.subTree return (subTree.anchor || subTree.el).nextSibling } else if (__FEATURE_SUSPENSE__ && shapeFlag & ShapeFlags.SUSPENSE) { - // TODO + // TODO Suspense } else if (__DEV__) { warn('Invalid HostVNode type:', type, `(${typeof type})`) } @@ -147,5 +151,22 @@ export function createHydrationFunctions( 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 }