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'
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
}
const cssTransitionProps = resolveTransitionProps(rawProps)
const tag = rawProps.tag || Fragment
prevChildren = children
- const slotChildren = slots.default ? slots.default() : []
- children = getTransitionRawChildren(slotChildren)
+ children = slots.default ? getTransitionRawChildren(slots.default()) : []
for (let i = 0; i < children.length; i++) {
const child = children[i]
}
}
- return createVNode(tag, null, slotChildren)
+ return createVNode(tag, null, children)
}
}
}