|
|
@@ -15,7 +15,7 @@ import { warn } from '../warning'
|
|
|
import { isKeepAlive } from './KeepAlive'
|
|
|
import { toRaw } from '@vue/reactivity'
|
|
|
import { callWithAsyncErrorHandling, ErrorCodes } from '../errorHandling'
|
|
|
-import { ShapeFlags } from '@vue/shared'
|
|
|
+import { ShapeFlags, PatchFlags } from '@vue/shared'
|
|
|
import { onBeforeUnmount, onMounted } from '../apiLifecycle'
|
|
|
import { RendererElement } from '../renderer'
|
|
|
|
|
|
@@ -427,21 +427,29 @@ export function getTransitionRawChildren(
|
|
|
keepComment: boolean = false
|
|
|
): VNode[] {
|
|
|
let ret: VNode[] = []
|
|
|
+ let keyedFragmentCount = 0
|
|
|
for (let i = 0; i < children.length; i++) {
|
|
|
const child = children[i]
|
|
|
// handle fragment children case, e.g. v-for
|
|
|
if (child.type === Fragment) {
|
|
|
+ if (child.patchFlag & PatchFlags.KEYED_FRAGMENT) keyedFragmentCount++
|
|
|
ret = ret.concat(
|
|
|
getTransitionRawChildren(child.children as VNode[], keepComment)
|
|
|
)
|
|
|
}
|
|
|
// comment placeholders should be skipped, e.g. v-if
|
|
|
- else if (
|
|
|
- child.type !== Comment ||
|
|
|
- (child.type === Comment && keepComment)
|
|
|
- ) {
|
|
|
+ else if (keepComment || child.type !== Comment) {
|
|
|
ret.push(child)
|
|
|
}
|
|
|
}
|
|
|
+ // #1126 if a transition children list contains multiple sub fragments, these
|
|
|
+ // fragments will be merged into a flat children array. Since each v-for
|
|
|
+ // fragment may contain different static bindings inside, we need to de-top
|
|
|
+ // these children to force full diffs to ensure correct behavior.
|
|
|
+ if (keyedFragmentCount > 1) {
|
|
|
+ for (let i = 0; i < ret.length; i++) {
|
|
|
+ ret[i].patchFlag = PatchFlags.BAIL
|
|
|
+ }
|
|
|
+ }
|
|
|
return ret
|
|
|
}
|