queuePostRenderEffect(() => transition!.enter(el!), parentSuspense)
} else {
const { leave, delayLeave, afterLeave } = transition!
- const remove = () => hostInsert(el!, container, anchor)
+ const remove = () => {
+ if (vnode.ctx!.isUnmounted) {
+ hostRemove(el!)
+ } else {
+ hostInsert(el!, container, anchor)
+ }
+ }
const performLeave = () => {
leave(el!, () => {
remove()
+import type { ElementHandle } from 'puppeteer'
import { E2E_TIMEOUT, setupPuppeteer } from './e2eUtils'
import path from 'node:path'
import { Transition, createApp, h, nextTick, ref } from 'vue'
},
E2E_TIMEOUT,
)
+
+ // #12860
+ test(
+ 'unmount children',
+ async () => {
+ const unmountSpy = vi.fn()
+ let storageContainer: ElementHandle<HTMLDivElement>
+ const setStorageContainer = (container: any) =>
+ (storageContainer = container)
+ await page().exposeFunction('unmountSpy', unmountSpy)
+ await page().exposeFunction('setStorageContainer', setStorageContainer)
+ await page().evaluate(() => {
+ const { unmountSpy, setStorageContainer } = window as any
+ const { createApp, ref, h, onUnmounted, getCurrentInstance } = (
+ window as any
+ ).Vue
+ createApp({
+ template: `
+ <div id="container">
+ <transition>
+ <KeepAlive :include="includeRef">
+ <TrueBranch v-if="toggle"></TrueBranch>
+ </KeepAlive>
+ </transition>
+ </div>
+ <button id="toggleBtn" @click="click">button</button>
+ `,
+ components: {
+ TrueBranch: {
+ name: 'TrueBranch',
+ setup() {
+ const instance = getCurrentInstance()
+ onUnmounted(() => {
+ unmountSpy()
+ setStorageContainer(instance.__keepAliveStorageContainer)
+ })
+ const count = ref(0)
+ return () => h('div', count.value)
+ },
+ },
+ },
+ setup: () => {
+ const includeRef = ref(['TrueBranch'])
+ const toggle = ref(true)
+ const click = () => {
+ toggle.value = !toggle.value
+ if (toggle.value) {
+ includeRef.value = ['TrueBranch']
+ } else {
+ includeRef.value = []
+ }
+ }
+ return { toggle, click, unmountSpy, includeRef }
+ },
+ }).mount('#app')
+ })
+
+ await transitionFinish()
+ expect(await html('#container')).toBe('<div>0</div>')
+
+ await click('#toggleBtn')
+ await transitionFinish()
+ expect(await html('#container')).toBe('<!--v-if-->')
+ expect(unmountSpy).toBeCalledTimes(1)
+ expect(await storageContainer!.evaluate(x => x.innerHTML)).toBe(``)
+ },
+ E2E_TIMEOUT,
+ )
})
describe('transition with Suspense', () => {