From cad35dc6c3fc5f81283c9820ab44bf257d7f9429 Mon Sep 17 00:00:00 2001 From: zhangyu96 Date: Thu, 28 Oct 2021 14:50:18 +0800 Subject: [PATCH] fix(transition-group): transition-group edge case --- .../src/components/TransitionGroup.ts | 27 +++++++++++++-- .../vue/__tests__/TransitionGroup.spec.ts | 33 +++++++++++++++++++ 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/packages/runtime-dom/src/components/TransitionGroup.ts b/packages/runtime-dom/src/components/TransitionGroup.ts index 8c5739ac151..5cf31c7702d 100644 --- a/packages/runtime-dom/src/components/TransitionGroup.ts +++ b/packages/runtime-dom/src/components/TransitionGroup.ts @@ -23,9 +23,12 @@ import { toRaw, compatUtils, DeprecationTypes, - ComponentOptions + ComponentOptions, + VNodeArrayChildren, + isVNode, + Comment } from '@vue/runtime-core' -import { extend } from '@vue/shared' +import { extend, PatchFlags, ShapeFlags } from '@vue/shared' interface Position { top: number @@ -115,7 +118,9 @@ const TransitionGroupImpl: ComponentOptions = { tag = 'span' } - prevChildren = children + if (children) { + prevChildren = children.map(c => storeTransitionVnode(c)) + } children = slots.default ? getTransitionRawChildren(slots.default()) : [] for (let i = 0; i < children.length; i++) { @@ -218,3 +223,19 @@ function hasCSSTransform( container.removeChild(clone) return hasTransform } + +// #4830 +// get the actual vnode when subTree is DEV_ROOT_FRAGMENT +// to access the right transition element +function storeTransitionVnode(c: VNode) { + if ( + __DEV__ && + c.shapeFlag & ShapeFlags.COMPONENT && + c.component!.subTree.patchFlag & PatchFlags.DEV_ROOT_FRAGMENT + ) { + const children = c.component!.subTree.children as VNodeArrayChildren + const vnode = children.find(c => isVNode(c) && c.type !== Comment) as VNode + return vnode + } + return c +} diff --git a/packages/vue/__tests__/TransitionGroup.spec.ts b/packages/vue/__tests__/TransitionGroup.spec.ts index 6ba05763801..99a66bd12bd 100644 --- a/packages/vue/__tests__/TransitionGroup.spec.ts +++ b/packages/vue/__tests__/TransitionGroup.spec.ts @@ -508,4 +508,37 @@ describe('e2e: TransitionGroup', () => { expect(` children must be keyed`).toHaveBeenWarned() }) + + test('DEV_ROOT_FRAGMENT transition item', async () => { + await page().evaluate(async () => { + const { createApp, ref } = (window as any).Vue + createApp({ + template: ` +
+ + + +
+ + `, + setup: () => { + const items = ref(['a']) + const click = () => items.value.push('b', 'c') + return { click, items } + }, + components: { + Comp: { + template: `
test
` + } + } + }).mount('#app') + }) + expect(await html('#container')).toBe(`
test
`) + + expect(await htmlWhenTransitionStart()).toBe( + `
test
` + + `
test
` + + `
test
` + ) + }) })