]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(transition-group): vue 2 compatible handling of transition-group w/ multiple...
authorEvan You <yyx990803@gmail.com>
Mon, 29 Jun 2020 22:15:53 +0000 (18:15 -0400)
committerEvan You <yyx990803@gmail.com>
Mon, 29 Jun 2020 22:16:10 +0000 (18:16 -0400)
fix #1126

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

index a3ab079bc606bd86cbb5dc441f97bc04eeeae564..b1ee5da685155bb4f456068d6849e02790621680 100644 (file)
@@ -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
 }
index d056eb5b587a26b9b153059800ca42cd696057f6..417f0b13eabe350a17bf70133090a0dc21ebc606 100644 (file)
@@ -100,8 +100,7 @@ const TransitionGroupImpl = {
       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]
@@ -126,7 +125,7 @@ const TransitionGroupImpl = {
         }
       }
 
-      return createVNode(tag, null, slotChildren)
+      return createVNode(tag, null, children)
     }
   }
 }