Skip to content

Commit 86d3972

Browse files
committed
fix(transition-group): vue 2 compatible handling of transition-group w/ multiple v-for children
fix #1126
1 parent d32aed0 commit 86d3972

File tree

2 files changed

+15
-8
lines changed

2 files changed

+15
-8
lines changed

packages/runtime-core/src/components/BaseTransition.ts

+13-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { warn } from '../warning'
1515
import { isKeepAlive } from './KeepAlive'
1616
import { toRaw } from '@vue/reactivity'
1717
import { callWithAsyncErrorHandling, ErrorCodes } from '../errorHandling'
18-
import { ShapeFlags } from '@vue/shared'
18+
import { ShapeFlags, PatchFlags } from '@vue/shared'
1919
import { onBeforeUnmount, onMounted } from '../apiLifecycle'
2020
import { RendererElement } from '../renderer'
2121

@@ -427,21 +427,29 @@ export function getTransitionRawChildren(
427427
keepComment: boolean = false
428428
): VNode[] {
429429
let ret: VNode[] = []
430+
let keyedFragmentCount = 0
430431
for (let i = 0; i < children.length; i++) {
431432
const child = children[i]
432433
// handle fragment children case, e.g. v-for
433434
if (child.type === Fragment) {
435+
if (child.patchFlag & PatchFlags.KEYED_FRAGMENT) keyedFragmentCount++
434436
ret = ret.concat(
435437
getTransitionRawChildren(child.children as VNode[], keepComment)
436438
)
437439
}
438440
// comment placeholders should be skipped, e.g. v-if
439-
else if (
440-
child.type !== Comment ||
441-
(child.type === Comment && keepComment)
442-
) {
441+
else if (keepComment || child.type !== Comment) {
443442
ret.push(child)
444443
}
445444
}
445+
// #1126 if a transition children list contains multiple sub fragments, these
446+
// fragments will be merged into a flat children array. Since each v-for
447+
// fragment may contain different static bindings inside, we need to de-top
448+
// these children to force full diffs to ensure correct behavior.
449+
if (keyedFragmentCount > 1) {
450+
for (let i = 0; i < ret.length; i++) {
451+
ret[i].patchFlag = PatchFlags.BAIL
452+
}
453+
}
446454
return ret
447455
}

packages/runtime-dom/src/components/TransitionGroup.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,7 @@ const TransitionGroupImpl = {
100100
const cssTransitionProps = resolveTransitionProps(rawProps)
101101
const tag = rawProps.tag || Fragment
102102
prevChildren = children
103-
const slotChildren = slots.default ? slots.default() : []
104-
children = getTransitionRawChildren(slotChildren)
103+
children = slots.default ? getTransitionRawChildren(slots.default()) : []
105104

106105
for (let i = 0; i < children.length; i++) {
107106
const child = children[i]
@@ -126,7 +125,7 @@ const TransitionGroupImpl = {
126125
}
127126
}
128127

129-
return createVNode(tag, null, slotChildren)
128+
return createVNode(tag, null, children)
130129
}
131130
}
132131
}

0 commit comments

Comments
 (0)