feat(portal): hydration support for portal disabled mode
This commit is contained in:
@@ -8,23 +8,17 @@ import {
|
||||
VNodeHook
|
||||
} from './vnode'
|
||||
import { flushPostFlushCbs } from './scheduler'
|
||||
import { ComponentInternalInstance } from './component'
|
||||
import { ComponentOptions, ComponentInternalInstance } from './component'
|
||||
import { invokeDirectiveHook } from './directives'
|
||||
import { warn } from './warning'
|
||||
import {
|
||||
PatchFlags,
|
||||
ShapeFlags,
|
||||
isReservedProp,
|
||||
isOn,
|
||||
isString
|
||||
} from '@vue/shared'
|
||||
import { PatchFlags, ShapeFlags, isReservedProp, isOn } from '@vue/shared'
|
||||
import { RendererInternals, invokeVNodeHook } from './renderer'
|
||||
import {
|
||||
SuspenseImpl,
|
||||
SuspenseBoundary,
|
||||
queueEffectWithSuspense
|
||||
} from './components/Suspense'
|
||||
import { ComponentOptions } from './apiOptions'
|
||||
import { PortalImpl } from './components/Portal'
|
||||
|
||||
export type RootHydrateFunction = (
|
||||
vnode: VNode<Node, Element>,
|
||||
@@ -182,8 +176,15 @@ export function createHydrationFunctions(
|
||||
if (domType !== DOMNodeTypes.COMMENT) {
|
||||
return onMismatch()
|
||||
}
|
||||
hydratePortal(vnode, parentComponent, parentSuspense, optimized)
|
||||
return nextSibling(node)
|
||||
return (vnode.type as typeof PortalImpl).hydrate(
|
||||
node,
|
||||
vnode,
|
||||
parentComponent,
|
||||
parentSuspense,
|
||||
optimized,
|
||||
rendererInternals,
|
||||
hydrateChildren
|
||||
)
|
||||
} else if (__FEATURE_SUSPENSE__ && shapeFlag & ShapeFlags.SUSPENSE) {
|
||||
return (vnode.type as typeof SuspenseImpl).hydrate(
|
||||
node,
|
||||
@@ -366,41 +367,6 @@ export function createHydrationFunctions(
|
||||
}
|
||||
}
|
||||
|
||||
interface PortalTargetElement extends Element {
|
||||
// last portal target
|
||||
_lpa?: Node | null
|
||||
}
|
||||
|
||||
const hydratePortal = (
|
||||
vnode: VNode,
|
||||
parentComponent: ComponentInternalInstance | null,
|
||||
parentSuspense: SuspenseBoundary | null,
|
||||
optimized: boolean
|
||||
) => {
|
||||
const targetSelector = vnode.props && vnode.props.target
|
||||
const target = (vnode.target = isString(targetSelector)
|
||||
? document.querySelector(targetSelector)
|
||||
: targetSelector)
|
||||
if (target && vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
|
||||
vnode.anchor = hydrateChildren(
|
||||
// if multiple portals rendered to the same target element, we need to
|
||||
// pick up from where the last portal finished instead of the first node
|
||||
(target as PortalTargetElement)._lpa || target.firstChild,
|
||||
vnode,
|
||||
target,
|
||||
parentComponent,
|
||||
parentSuspense,
|
||||
optimized
|
||||
)
|
||||
;(target as PortalTargetElement)._lpa = nextSibling(vnode.anchor as Node)
|
||||
} else if (__DEV__) {
|
||||
warn(
|
||||
`Attempting to hydrate portal but target ${targetSelector} does not ` +
|
||||
`exist in server-rendered markup.`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const handleMismtach = (
|
||||
node: Node,
|
||||
vnode: VNode,
|
||||
|
||||
Reference in New Issue
Block a user