diff --git a/packages/runtime-core/__tests__/apiApp.spec.ts b/packages/runtime-core/__tests__/apiApp.spec.ts index 31096954e6d..7ade99e9e94 100644 --- a/packages/runtime-core/__tests__/apiApp.spec.ts +++ b/packages/runtime-core/__tests__/apiApp.spec.ts @@ -46,6 +46,26 @@ describe('api: createApp', () => { expect(`already been mounted`).toHaveBeenWarned() }) + test('unmount', () => { + const Comp = { + props: { + count: { + default: 0 + } + }, + setup(props: { count: number }) { + return () => props.count + } + } + + const root = nodeOps.createElement('div') + const app = createApp() + app.mount(Comp, root) + + app.unmount(root) + expect(serializeInner(root)).toBe(``) + }) + test('provide', () => { const app = createApp() app.provide('foo', 1) diff --git a/packages/runtime-core/src/apiCreateApp.ts b/packages/runtime-core/src/apiCreateApp.ts index a07b14ca0d4..fdd377d0264 100644 --- a/packages/runtime-core/src/apiCreateApp.ts +++ b/packages/runtime-core/src/apiCreateApp.ts @@ -24,6 +24,7 @@ export interface App { rootContainer: HostElement | string, rootProps?: Data ): ComponentPublicInstance + unmount(rootContainer: HostElement | string): void provide(key: InjectionKey | string, value: T): this } @@ -197,6 +198,10 @@ export function createAppAPI( } }, + unmount(rootContainer: HostElement) { + render(null, rootContainer) + }, + provide(key, value) { if (__DEV__ && key in context.provides) { warn( diff --git a/packages/runtime-dom/src/index.ts b/packages/runtime-dom/src/index.ts index 62885cb2fb0..cc487d16690 100644 --- a/packages/runtime-dom/src/index.ts +++ b/packages/runtime-dom/src/index.ts @@ -29,7 +29,7 @@ export const createApp = (): App => { }) } - const mount = app.mount + const { mount, unmount } = app app.mount = (component, container, props): any => { if (isString(container)) { container = document.querySelector(container)! @@ -51,6 +51,17 @@ export const createApp = (): App => { container.innerHTML = '' return mount(component, container, props) } + app.unmount = container => { + if (isString(container)) { + container = document.querySelector(container)! + if (!container) { + __DEV__ && + warn(`Failed to unmount app: mount target selector returned null.`) + return + } + } + unmount(container) + } return app }