Skip to content

Commit 47a6a84

Browse files
committed
fix(core): clone mounted hoisted vnodes on patch
...since they may need to be checked as fragment child
1 parent eda495e commit 47a6a84

File tree

2 files changed

+25
-16
lines changed

2 files changed

+25
-16
lines changed

packages/runtime-core/src/renderer.ts

+20-16
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
Fragment,
44
Comment,
55
Portal,
6+
cloneIfMounted,
67
normalizeVNode,
78
VNode,
89
VNodeChildren,
@@ -438,9 +439,9 @@ export function createRenderer<
438439
start: number = 0
439440
) {
440441
for (let i = start; i < children.length; i++) {
441-
const child = optimized
442-
? (children[i] as HostVNode)
443-
: (children[i] = normalizeVNode(children[i]))
442+
const child = (children[i] = optimized
443+
? cloneIfMounted(children[i] as HostVNode)
444+
: normalizeVNode(children[i]))
444445
patch(
445446
null,
446447
child,
@@ -1198,9 +1199,9 @@ export function createRenderer<
11981199
const commonLength = Math.min(oldLength, newLength)
11991200
let i
12001201
for (i = 0; i < commonLength; i++) {
1201-
const nextChild = optimized
1202-
? (c2[i] as HostVNode)
1203-
: (c2[i] = normalizeVNode(c2[i]))
1202+
const nextChild = (c2[i] = optimized
1203+
? cloneIfMounted(c2[i] as HostVNode)
1204+
: normalizeVNode(c2[i]))
12041205
patch(
12051206
c1[i],
12061207
nextChild,
@@ -1251,9 +1252,9 @@ export function createRenderer<
12511252
// (a b) d e
12521253
while (i <= e1 && i <= e2) {
12531254
const n1 = c1[i]
1254-
const n2 = optimized
1255-
? (c2[i] as HostVNode)
1256-
: (c2[i] = normalizeVNode(c2[i]))
1255+
const n2 = (c2[i] = optimized
1256+
? cloneIfMounted(c2[i] as HostVNode)
1257+
: normalizeVNode(c2[i]))
12571258
if (isSameVNodeType(n1, n2)) {
12581259
patch(
12591260
n1,
@@ -1276,9 +1277,9 @@ export function createRenderer<
12761277
// d e (b c)
12771278
while (i <= e1 && i <= e2) {
12781279
const n1 = c1[e1]
1279-
const n2 = optimized
1280-
? (c2[e2] as HostVNode)
1281-
: (c2[e2] = normalizeVNode(c2[e2]))
1280+
const n2 = (c2[e2] = optimized
1281+
? cloneIfMounted(c2[e2] as HostVNode)
1282+
: normalizeVNode(c2[e2]))
12821283
if (isSameVNodeType(n1, n2)) {
12831284
patch(
12841285
n1,
@@ -1309,10 +1310,13 @@ export function createRenderer<
13091310
const nextPos = e2 + 1
13101311
const anchor =
13111312
nextPos < l2 ? (c2[nextPos] as HostVNode).el : parentAnchor
1313+
const n2 = (c2[i] = optimized
1314+
? cloneIfMounted(c2[i] as HostVNode)
1315+
: normalizeVNode(c2[i]))
13121316
while (i <= e2) {
13131317
patch(
13141318
null,
1315-
optimized ? (c2[i] as HostVNode) : (c2[i] = normalizeVNode(c2[i])),
1319+
n2,
13161320
container,
13171321
anchor,
13181322
parentComponent,
@@ -1349,9 +1353,9 @@ export function createRenderer<
13491353
// 5.1 build key:index map for newChildren
13501354
const keyToNewIndexMap: Map<string | number, number> = new Map()
13511355
for (i = s2; i <= e2; i++) {
1352-
const nextChild = optimized
1353-
? (c2[i] as HostVNode)
1354-
: (c2[i] = normalizeVNode(c2[i]))
1356+
const nextChild = (c2[i] = optimized
1357+
? cloneIfMounted(c2[i] as HostVNode)
1358+
: normalizeVNode(c2[i]))
13551359
if (nextChild.key != null) {
13561360
if (__DEV__ && keyToNewIndexMap.has(nextChild.key)) {
13571361
warn(

packages/runtime-core/src/vnode.ts

+5
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,11 @@ export function normalizeVNode<T, U>(child: VNodeChild<T, U>): VNode<T, U> {
353353
}
354354
}
355355

356+
// optimized normalization for template-compiled render fns
357+
export function cloneIfMounted(child: VNode): VNode {
358+
return child.el == null ? child : cloneVNode(child)
359+
}
360+
356361
export function normalizeChildren(vnode: VNode, children: unknown) {
357362
let type = 0
358363
if (children == null) {

0 commit comments

Comments
 (0)