fix(transition): fix broken leave transition on dev root fragment (#5268)

This commit is contained in:
edison 2022-04-14 17:10:41 +08:00 committed by GitHub
parent 71c9536625
commit 767d212d20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 88 additions and 4 deletions

View File

@ -2159,7 +2159,23 @@ function baseCreateRenderer(
const remove: RemoveFn = vnode => { const remove: RemoveFn = vnode => {
const { type, el, anchor, transition } = vnode const { type, el, anchor, transition } = vnode
if (type === Fragment) { if (type === Fragment) {
removeFragment(el!, anchor!) if (
__DEV__ &&
vnode.patchFlag > 0 &&
vnode.patchFlag & PatchFlags.DEV_ROOT_FRAGMENT &&
transition &&
!transition.persisted
) {
;(vnode.children as VNode[]).forEach(child => {
if (child.type === Comment) {
hostRemove(child.el!)
} else {
remove(child)
}
})
} else {
removeFragment(el!, anchor!)
}
return return
} }

View File

@ -1979,9 +1979,7 @@ describe('e2e: Transition', () => {
</div> </div>
` `
}).mount(document.createElement('div')) }).mount(document.createElement('div'))
expect( expect(`invalid <transition> mode: none`).toHaveBeenWarned()
`invalid <transition> mode: none`
).toHaveBeenWarned()
}) })
// #3227 // #3227
@ -2023,4 +2021,74 @@ describe('e2e: Transition', () => {
expect(outerSpy).toHaveBeenCalledTimes(1) expect(outerSpy).toHaveBeenCalledTimes(1)
expect(root.innerHTML).toBe(`<!---->`) expect(root.innerHTML).toBe(`<!---->`)
}) })
test(
'should work with dev root fragment',
async () => {
await page().evaluate(() => {
const { createApp, ref } = (window as any).Vue
createApp({
components: {
Comp: {
template: `
<!-- Broken! -->
<div><slot /></div>
`
}
},
template: `
<div id="container">
<transition>
<Comp class="test" v-if="toggle">
<div>content</div>
</Comp>
</transition>
</div>
<button id="toggleBtn" @click="click">button</button>
`,
setup: () => {
const toggle = ref(true)
const click = () => (toggle.value = !toggle.value)
return { toggle, click }
}
}).mount('#app')
})
expect(await html('#container')).toBe(
'<!-- Broken! --><div class="test"><div>content</div></div>'
)
// leave
expect(await classWhenTransitionStart()).toStrictEqual([
'test',
'v-leave-from',
'v-leave-active'
])
await nextFrame()
expect(await classList('.test')).toStrictEqual([
'test',
'v-leave-active',
'v-leave-to'
])
await transitionFinish()
expect(await html('#container')).toBe('<!--v-if-->')
// enter
expect(await classWhenTransitionStart()).toStrictEqual([
'test',
'v-enter-from',
'v-enter-active'
])
await nextFrame()
expect(await classList('.test')).toStrictEqual([
'test',
'v-enter-active',
'v-enter-to'
])
await transitionFinish()
expect(await html('#container')).toBe(
'<!-- Broken! --><div class="test"><div>content</div></div>'
)
},
E2E_TIMEOUT
)
}) })