diff --git a/src/mount.ts b/src/mount.ts index 04d78c868..917489fbe 100644 --- a/src/mount.ts +++ b/src/mount.ts @@ -100,13 +100,26 @@ export function mount( } to.appendChild(el) - app.onUnmount(() => { + const removeContainer = () => { // The wrapper may already have been manually unmounted before auto-unmount // runs, so the container can already be removed from its parent. if (el.parentNode === to) { to.removeChild(el) } - }) + } + if (app.onUnmount) { + app.onUnmount(removeContainer) + } else { + // app.onUnmount is only available since Vue 3.5 + const unmount = app.unmount + app.unmount = () => { + try { + unmount() + } finally { + removeContainer() + } + } + } } const vm = app.mount(el) if (errorsOnMount.length) { diff --git a/tests/mount.spec.ts b/tests/mount.spec.ts index 534771003..619c68908 100644 --- a/tests/mount.spec.ts +++ b/tests/mount.spec.ts @@ -118,4 +118,25 @@ describe('mount: general tests', () => { wrapper.unmount() expect(document.body.firstChild, 'Container should be empty').toBeNull() }) + + // app.onUnmount only exists since Vue 3.5 + it('supports attachTo without app.onUnmount', () => { + const wrapper = mount(Hello, { + props: { msg: 'Hello world' }, + attachTo: document.body, + global: { + plugins: [ + { + install(app: any) { + app.onUnmount = undefined + } + } + ] + } + }) + expect(document.body.firstChild).toBeInstanceOf(HTMLDivElement) + + wrapper.unmount() + expect(document.body.firstChild).toBeNull() + }) })