From 890ca8aa346e77002e0ffbc497018bdc5a6f8125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=AB=E9=9B=A8=E6=B0=B4=E8=BF=87=E6=BB=A4=E7=9A=84?= =?UTF-8?q?=E7=A9=BA=E6=B0=94?= <958414905@qq.com> Date: Tue, 15 Sep 2020 08:50:06 +0800 Subject: [PATCH] fix(keep-alive): should use onMounted and onUpdated to invoke cacheSubtree (#1984) --- .../__tests__/components/KeepAlive.spec.ts | 42 +++++++++++++++++++ .../runtime-core/src/components/KeepAlive.ts | 8 ++-- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/packages/runtime-core/__tests__/components/KeepAlive.spec.ts b/packages/runtime-core/__tests__/components/KeepAlive.spec.ts index e1bf3f49b0e..27db922a264 100644 --- a/packages/runtime-core/__tests__/components/KeepAlive.spec.ts +++ b/packages/runtime-core/__tests__/components/KeepAlive.spec.ts @@ -131,6 +131,48 @@ describe('KeepAlive', () => { assertHookCalls(two, [1, 1, 2, 2, 1]) }) + test('should call correct lifecycle hooks when toggle the KeepAlive first', async () => { + const toggle = ref(true) + const viewRef = ref('one') + const App = { + render() { + return toggle.value ? h(KeepAlive, () => h(views[viewRef.value])) : null + } + } + render(h(App), root) + + expect(serializeInner(root)).toBe(`
one
`) + assertHookCalls(one, [1, 1, 1, 0, 0]) + assertHookCalls(two, [0, 0, 0, 0, 0]) + + // should unmount 'one' component when toggle the KeepAlive first + toggle.value = false + await nextTick() + expect(serializeInner(root)).toBe(``) + assertHookCalls(one, [1, 1, 1, 1, 1]) + assertHookCalls(two, [0, 0, 0, 0, 0]) + + toggle.value = true + await nextTick() + expect(serializeInner(root)).toBe(`
one
`) + assertHookCalls(one, [2, 2, 2, 1, 1]) + assertHookCalls(two, [0, 0, 0, 0, 0]) + + // 1. the first time toggle kept-alive component + viewRef.value = 'two' + await nextTick() + expect(serializeInner(root)).toBe(`
two
`) + assertHookCalls(one, [2, 2, 2, 2, 1]) + assertHookCalls(two, [1, 1, 1, 0, 0]) + + // 2. should unmount all components including cached + toggle.value = false + await nextTick() + expect(serializeInner(root)).toBe(``) + assertHookCalls(one, [2, 2, 2, 2, 2]) + assertHookCalls(two, [1, 1, 1, 1, 1]) + }) + test('should call lifecycle hooks on nested components', async () => { one.render = () => h(two) diff --git a/packages/runtime-core/src/components/KeepAlive.ts b/packages/runtime-core/src/components/KeepAlive.ts index b32a6ca2795..6ef7f5f387f 100644 --- a/packages/runtime-core/src/components/KeepAlive.ts +++ b/packages/runtime-core/src/components/KeepAlive.ts @@ -13,8 +13,8 @@ import { onBeforeUnmount, injectHook, onUnmounted, - onBeforeMount, - onBeforeUpdate + onMounted, + onUpdated } from '../apiLifecycle' import { isString, @@ -187,8 +187,8 @@ const KeepAliveImpl = { cache.set(pendingCacheKey, instance.subTree) } } - onBeforeMount(cacheSubtree) - onBeforeUpdate(cacheSubtree) + onMounted(cacheSubtree) + onUpdated(cacheSubtree) onBeforeUnmount(() => { cache.forEach(cached => {