diff --git a/packages/runtime-core/src/components/Suspense.ts b/packages/runtime-core/src/components/Suspense.ts index 85001f500cf..b19716bb615 100644 --- a/packages/runtime-core/src/components/Suspense.ts +++ b/packages/runtime-core/src/components/Suspense.ts @@ -552,6 +552,7 @@ function createSuspenseBoundary( ) queuePostFlushCb(effects) } + activeBranch!.transition!.afterLeave = undefined } } // unmount current active tree diff --git a/packages/runtime-dom/__tests__/createApp.spec.ts b/packages/runtime-dom/__tests__/createApp.spec.ts index 9a8d05df2df..7a865908847 100644 --- a/packages/runtime-dom/__tests__/createApp.spec.ts +++ b/packages/runtime-dom/__tests__/createApp.spec.ts @@ -1,4 +1,5 @@ -import { createApp, h } from '../src' +import { createApp, h, ref } from '../src' +import { defineComponent, onMounted, shallowRef } from 'vue' describe('createApp for dom', () => { // #2926 @@ -39,4 +40,62 @@ describe('createApp for dom', () => { // ensure no mutation happened to Root object expect(originalObj).toMatchObject(Root) }) + + test('When the app is unmounted, the onMounted of suspense in Transition should not be called', async () => { + const onPage2Mounted = vi.fn() + let page1Comp: any + const Page1 = defineComponent({ + name: 'Page1', + setup() { + return () => h('div', null, 'page1') + }, + }) + const Page2 = defineComponent({ + name: 'Page2', + setup() { + onMounted(onPage2Mounted) + return () => h('div', null, 'page2') + }, + }) + const Component = shallowRef(Page1) + const page = ref(null) + const App = defineComponent({ + setup() { + return { + Component, + page, + } + }, + template: ` +
+ +
+ `, + }) + const app = createApp(App) + app.mount(document.createElement('div')) + await new Promise(resolve => { + setTimeout(resolve, 500) + }) + page1Comp = page.value + Component.value = Page2 + await new Promise(resolve => { + setTimeout(resolve, 500) + }) + expect(onPage2Mounted).toHaveBeenCalledTimes(1) + app.unmount() + await new Promise(resolve => { + setTimeout(resolve, 500) + }) + expect(onPage2Mounted).toHaveBeenCalledTimes(1) + expect(page1Comp._.vnode.transition.afterLeave).toBe(undefined) + }) })