const remove: RemoveFn = vnode => {
const { type, el, anchor, transition } = vnode
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
}
</div>
`
}).mount(document.createElement('div'))
- expect(
- `invalid <transition> mode: none`
- ).toHaveBeenWarned()
+ expect(`invalid <transition> mode: none`).toHaveBeenWarned()
})
// #3227
expect(outerSpy).toHaveBeenCalledTimes(1)
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
+ )
})