@@ -164,7 +164,9 @@ const BaseTransitionImpl: ComponentOptions = {
164
164
if (
165
165
__DEV__ &&
166
166
mode &&
167
- mode !== 'in-out' && mode !== 'out-in' && mode !== 'default'
167
+ mode !== 'in-out' &&
168
+ mode !== 'out-in' &&
169
+ mode !== 'default'
168
170
) {
169
171
warn ( `invalid <transition> mode: ${ mode } ` )
170
172
}
@@ -460,22 +462,28 @@ export function setTransitionHooks(vnode: VNode, hooks: TransitionHooks) {
460
462
461
463
export function getTransitionRawChildren (
462
464
children : VNode [ ] ,
463
- keepComment : boolean = false
465
+ keepComment : boolean = false ,
466
+ parentKey ?: VNode [ 'key' ]
464
467
) : VNode [ ] {
465
468
let ret : VNode [ ] = [ ]
466
469
let keyedFragmentCount = 0
467
470
for ( let i = 0 ; i < children . length ; i ++ ) {
468
- const child = children [ i ]
471
+ let child = children [ i ]
472
+ // #5360 inherit parent key in case of <template v-for>
473
+ const key =
474
+ parentKey == null
475
+ ? child . key
476
+ : String ( parentKey ) + String ( child . key != null ? child . key : i )
469
477
// handle fragment children case, e.g. v-for
470
478
if ( child . type === Fragment ) {
471
479
if ( child . patchFlag & PatchFlags . KEYED_FRAGMENT ) keyedFragmentCount ++
472
480
ret = ret . concat (
473
- getTransitionRawChildren ( child . children as VNode [ ] , keepComment )
481
+ getTransitionRawChildren ( child . children as VNode [ ] , keepComment , key )
474
482
)
475
483
}
476
484
// comment placeholders should be skipped, e.g. v-if
477
485
else if ( keepComment || child . type !== Comment ) {
478
- ret . push ( child )
486
+ ret . push ( key != null ? cloneVNode ( child , { key } ) : child )
479
487
}
480
488
}
481
489
// #1126 if a transition children list contains multiple sub fragments, these
0 commit comments