diff --git a/packages/runtime-core/src/components/KeepAlive.ts b/packages/runtime-core/src/components/KeepAlive.ts index 1ef589d74a6..5ad0367f696 100644 --- a/packages/runtime-core/src/components/KeepAlive.ts +++ b/packages/runtime-core/src/components/KeepAlive.ts @@ -182,7 +182,8 @@ const KeepAliveImpl = { // cache sub tree in beforeMount/Update (i.e. right after the render) let pendingCacheKey: CacheKey | null = null const cacheSubtree = () => { - if (pendingCacheKey) { + // fix #1621, the pendingCacheKey could be 0 + if (pendingCacheKey != null) { cache.set(pendingCacheKey, instance.subTree) } } diff --git a/packages/vue/__tests__/index.spec.ts b/packages/vue/__tests__/index.spec.ts index 6303c157c8d..304bc79b60d 100644 --- a/packages/vue/__tests__/index.spec.ts +++ b/packages/vue/__tests__/index.spec.ts @@ -1,4 +1,4 @@ -import { createApp } from '../src' +import { createApp, ref, nextTick } from '../src' import { mockWarn } from '@vue/shared' describe('compiler + runtime integration', () => { @@ -18,6 +18,62 @@ describe('compiler + runtime integration', () => { expect(container.innerHTML).toBe(`0`) }) + it('keep-alive with compiler + runtime integration', async () => { + const container = document.createElement('div') + const one = { + name: 'one', + template: 'one', + created: jest.fn(), + mounted: jest.fn(), + activated: jest.fn(), + deactivated: jest.fn(), + destroyed: jest.fn() + } + + const toggle = ref(true) + + const App = { + template: ` + + + + `, + data() { + return { + toggle + } + }, + components: { + One: one + } + } + createApp(App).mount(container) + expect(container.innerHTML).toBe(`one`) + expect(one.created).toHaveBeenCalledTimes(1) + expect(one.mounted).toHaveBeenCalledTimes(1) + expect(one.activated).toHaveBeenCalledTimes(1) + expect(one.deactivated).toHaveBeenCalledTimes(0) + expect(one.destroyed).toHaveBeenCalledTimes(0) + + toggle.value = false; + await nextTick() + expect(container.innerHTML).toBe(``) + expect(one.created).toHaveBeenCalledTimes(1) + expect(one.mounted).toHaveBeenCalledTimes(1) + expect(one.activated).toHaveBeenCalledTimes(1) + expect(one.deactivated).toHaveBeenCalledTimes(1) + expect(one.destroyed).toHaveBeenCalledTimes(0) + + toggle.value = true; + await nextTick() + expect(container.innerHTML).toBe(`one`) + expect(one.created).toHaveBeenCalledTimes(1) + expect(one.mounted).toHaveBeenCalledTimes(1) + expect(one.activated).toHaveBeenCalledTimes(2) + expect(one.deactivated).toHaveBeenCalledTimes(1) + expect(one.destroyed).toHaveBeenCalledTimes(0) + }) + it('should support runtime template via CSS ID selector', () => { const container = document.createElement('div') const template = document.createElement('div')