fix(runtime-core): handle dynamicChildren when portal is used as a block

This commit is contained in:
Evan You 2019-10-16 17:43:33 -04:00
parent 4b2b29efa1
commit 1722dc05c5

View File

@ -495,25 +495,14 @@ export function createRenderer<
}
if (dynamicChildren != null) {
// children fast path
const oldDynamicChildren = n1.dynamicChildren!
for (let i = 0; i < dynamicChildren.length; i++) {
const oldVNode = oldDynamicChildren[i]
patch(
oldVNode,
dynamicChildren[i],
// in the case of a Fragment, we need to provide the actual parent
// of the Fragment itself so it can move its children. In other cases,
// the parent container is not actually used so we just pass the
// block element here to avoid a DOM parentNode call.
oldVNode.type === Fragment ? hostParentNode(oldVNode.el!)! : el,
null,
patchBlockChildren(
n1.dynamicChildren!,
dynamicChildren,
el,
parentComponent,
parentSuspense,
isSVG,
true
isSVG
)
}
} else if (!optimized) {
// full diff
patchChildren(n1, n2, el, null, parentComponent, parentSuspense, isSVG)
@ -526,6 +515,36 @@ export function createRenderer<
}
}
// The fast path for blocks.
function patchBlockChildren(
oldChildren: HostVNode[],
newChildren: HostVNode[],
fallbackContainer: HostElement,
parentComponent: ComponentInternalInstance | null,
parentSuspense: HostSuspenseBoundary | null,
isSVG: boolean
) {
for (let i = 0; i < newChildren.length; i++) {
const oldVNode = oldChildren[i]
patch(
oldVNode,
newChildren[i],
// in the case of a Fragment, we need to provide the actual parent
// of the Fragment itself so it can move its children. In other cases,
// the parent container is not actually used so we just pass the
// block element here to avoid a DOM parentNode call.
oldVNode.type === Fragment
? hostParentNode(oldVNode.el!)!
: fallbackContainer,
null,
parentComponent,
parentSuspense,
isSVG,
true
)
}
}
function patchProps(
el: HostElement,
vnode: HostVNode,
@ -654,6 +673,16 @@ export function createRenderer<
const target = (n2.target = n1.target)!
if (patchFlag === PatchFlags.TEXT) {
hostSetElementText(target, children as string)
} else if (n2.dynamicChildren) {
// fast path when the portal happens to be a block root
patchBlockChildren(
n1.dynamicChildren!,
n2.dynamicChildren,
container,
parentComponent,
parentSuspense,
isSVG
)
} else if (!optimized) {
patchChildren(
n1,