Skip to content

Commit 1722dc0

Browse files
committed
fix(runtime-core): handle dynamicChildren when portal is used as a block
1 parent 4b2b29e commit 1722dc0

File tree

1 file changed

+48
-19
lines changed

1 file changed

+48
-19
lines changed

packages/runtime-core/src/createRenderer.ts

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -495,25 +495,14 @@ export function createRenderer<
495495
}
496496

497497
if (dynamicChildren != null) {
498-
// children fast path
499-
const oldDynamicChildren = n1.dynamicChildren!
500-
for (let i = 0; i < dynamicChildren.length; i++) {
501-
const oldVNode = oldDynamicChildren[i]
502-
patch(
503-
oldVNode,
504-
dynamicChildren[i],
505-
// in the case of a Fragment, we need to provide the actual parent
506-
// of the Fragment itself so it can move its children. In other cases,
507-
// the parent container is not actually used so we just pass the
508-
// block element here to avoid a DOM parentNode call.
509-
oldVNode.type === Fragment ? hostParentNode(oldVNode.el!)! : el,
510-
null,
511-
parentComponent,
512-
parentSuspense,
513-
isSVG,
514-
true
515-
)
516-
}
498+
patchBlockChildren(
499+
n1.dynamicChildren!,
500+
dynamicChildren,
501+
el,
502+
parentComponent,
503+
parentSuspense,
504+
isSVG
505+
)
517506
} else if (!optimized) {
518507
// full diff
519508
patchChildren(n1, n2, el, null, parentComponent, parentSuspense, isSVG)
@@ -526,6 +515,36 @@ export function createRenderer<
526515
}
527516
}
528517

518+
// The fast path for blocks.
519+
function patchBlockChildren(
520+
oldChildren: HostVNode[],
521+
newChildren: HostVNode[],
522+
fallbackContainer: HostElement,
523+
parentComponent: ComponentInternalInstance | null,
524+
parentSuspense: HostSuspenseBoundary | null,
525+
isSVG: boolean
526+
) {
527+
for (let i = 0; i < newChildren.length; i++) {
528+
const oldVNode = oldChildren[i]
529+
patch(
530+
oldVNode,
531+
newChildren[i],
532+
// in the case of a Fragment, we need to provide the actual parent
533+
// of the Fragment itself so it can move its children. In other cases,
534+
// the parent container is not actually used so we just pass the
535+
// block element here to avoid a DOM parentNode call.
536+
oldVNode.type === Fragment
537+
? hostParentNode(oldVNode.el!)!
538+
: fallbackContainer,
539+
null,
540+
parentComponent,
541+
parentSuspense,
542+
isSVG,
543+
true
544+
)
545+
}
546+
}
547+
529548
function patchProps(
530549
el: HostElement,
531550
vnode: HostVNode,
@@ -654,6 +673,16 @@ export function createRenderer<
654673
const target = (n2.target = n1.target)!
655674
if (patchFlag === PatchFlags.TEXT) {
656675
hostSetElementText(target, children as string)
676+
} else if (n2.dynamicChildren) {
677+
// fast path when the portal happens to be a block root
678+
patchBlockChildren(
679+
n1.dynamicChildren!,
680+
n2.dynamicChildren,
681+
container,
682+
parentComponent,
683+
parentSuspense,
684+
isSVG
685+
)
657686
} else if (!optimized) {
658687
patchChildren(
659688
n1,

0 commit comments

Comments
 (0)