@@ -15,7 +15,7 @@ import { warn } from '../warning'
15
15
import { isKeepAlive } from './KeepAlive'
16
16
import { toRaw } from '@vue/reactivity'
17
17
import { callWithAsyncErrorHandling , ErrorCodes } from '../errorHandling'
18
- import { ShapeFlags } from '@vue/shared'
18
+ import { ShapeFlags , PatchFlags } from '@vue/shared'
19
19
import { onBeforeUnmount , onMounted } from '../apiLifecycle'
20
20
import { RendererElement } from '../renderer'
21
21
@@ -427,21 +427,29 @@ export function getTransitionRawChildren(
427
427
keepComment : boolean = false
428
428
) : VNode [ ] {
429
429
let ret : VNode [ ] = [ ]
430
+ let keyedFragmentCount = 0
430
431
for ( let i = 0 ; i < children . length ; i ++ ) {
431
432
const child = children [ i ]
432
433
// handle fragment children case, e.g. v-for
433
434
if ( child . type === Fragment ) {
435
+ if ( child . patchFlag & PatchFlags . KEYED_FRAGMENT ) keyedFragmentCount ++
434
436
ret = ret . concat (
435
437
getTransitionRawChildren ( child . children as VNode [ ] , keepComment )
436
438
)
437
439
}
438
440
// 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 ) {
443
442
ret . push ( child )
444
443
}
445
444
}
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
+ }
446
454
return ret
447
455
}
0 commit comments