diff --git a/packages/runtime-vapor/__tests__/components/KeepAlive.spec.ts b/packages/runtime-vapor/__tests__/components/KeepAlive.spec.ts
index ea1ee8527..4cd8727f0 100644
--- a/packages/runtime-vapor/__tests__/components/KeepAlive.spec.ts
+++ b/packages/runtime-vapor/__tests__/components/KeepAlive.spec.ts
@@ -365,7 +365,7 @@ describe('VaporKeepAlive', () => {
expect(spy).toHaveBeenCalledTimes(1)
})
- test.todo('should call correct hooks for nested keep-alive', async () => {
+ test('should call correct hooks for nested keep-alive', async () => {
const toggle2 = ref(true)
const one = defineVaporComponent({
name: 'one',
@@ -431,42 +431,42 @@ describe('VaporKeepAlive', () => {
// the activated hook of two is not called
assertHookCalls(twoHooks, [1, 1, 3, 2, 0])
- // toggle1.value = false
- // await nextTick()
- // expect(html()).toBe(``)
- // assertHookCalls(oneHooks, [1, 1, 2, 2, 0])
- // assertHookCalls(twoHooks, [1, 1, 3, 3, 0])
+ toggle1.value = false
+ await nextTick()
+ expect(html()).toBe(``)
+ assertHookCalls(oneHooks, [1, 1, 2, 2, 0])
+ assertHookCalls(twoHooks, [1, 1, 3, 3, 0])
- // // toggle nested instance when parent is deactivated
- // toggle2.value = false
- // await nextTick()
- // expect(html()).toBe(``)
- // assertHookCalls(oneHooks, [1, 1, 2, 2, 0])
- // // assertHookCalls(twoHooks, [1, 1, 3, 3, 0]) // should not be affected
+ // toggle nested instance when parent is deactivated
+ toggle2.value = false
+ await nextTick()
+ expect(html()).toBe(``)
+ assertHookCalls(oneHooks, [1, 1, 2, 2, 0])
+ assertHookCalls(twoHooks, [1, 1, 3, 3, 0]) // should not be affected
- // toggle2.value = true
- // await nextTick()
- // expect(html()).toBe(``)
- // assertHookCalls(oneHooks, [1, 1, 2, 2, 0])
- // // assertHookCalls(twoHooks, [1, 1, 3, 3, 0]) // should not be affected
+ toggle2.value = true
+ await nextTick()
+ expect(html()).toBe(``)
+ assertHookCalls(oneHooks, [1, 1, 2, 2, 0])
+ assertHookCalls(twoHooks, [1, 1, 3, 3, 0]) // should not be affected
- // toggle1.value = true
- // await nextTick()
- // expect(html()).toBe(`
two
`)
- // assertHookCalls(oneHooks, [1, 1, 3, 2, 0])
- // // assertHookCalls(twoHooks, [1, 1, 4, 3, 0])
+ toggle1.value = true
+ await nextTick()
+ expect(html()).toBe(`two
`)
+ assertHookCalls(oneHooks, [1, 1, 3, 2, 0])
+ assertHookCalls(twoHooks, [1, 1, 4, 3, 0])
- // toggle1.value = false
- // toggle2.value = false
- // await nextTick()
- // expect(html()).toBe(``)
- // assertHookCalls(oneHooks, [1, 1, 3, 3, 0])
- // // assertHookCalls(twoHooks, [1, 1, 4, 4, 0])
+ toggle1.value = false
+ toggle2.value = false
+ await nextTick()
+ expect(html()).toBe(``)
+ assertHookCalls(oneHooks, [1, 1, 3, 3, 0])
+ assertHookCalls(twoHooks, [1, 1, 4, 4, 0])
- // toggle1.value = true
- // await nextTick()
- // expect(html()).toBe(``)
- // assertHookCalls(oneHooks, [1, 1, 4, 3, 0])
- // // assertHookCalls(twoHooks, [1, 1, 4, 4, 0]) // should remain inactive
+ toggle1.value = true
+ await nextTick()
+ expect(html()).toBe(``)
+ assertHookCalls(oneHooks, [1, 1, 4, 3, 0])
+ assertHookCalls(twoHooks, [1, 1, 4, 4, 0]) // should remain inactive
})
})
diff --git a/packages/runtime-vapor/src/block.ts b/packages/runtime-vapor/src/block.ts
index c93e94612..c9d81986b 100644
--- a/packages/runtime-vapor/src/block.ts
+++ b/packages/runtime-vapor/src/block.ts
@@ -60,8 +60,10 @@ export class DynamicFragment extends VaporFragment {
;(instance as KeepAliveInstance).process(
this.nodes as VaporComponentInstance,
)
+ unmountComponent(this.nodes as VaporComponentInstance)
+ } else {
+ this.scope.stop()
}
- this.scope.stop()
parent && remove(this.nodes, parent)
}
@@ -128,7 +130,7 @@ export function insert(
parent.insertBefore(block, anchor)
}
} else if (isVaporComponent(block)) {
- if (block.isMounted) {
+ if (block.isMounted && !block.isDeactivated) {
insert(block.block!, parent, anchor)
} else {
mountComponent(block, parent, anchor)
diff --git a/packages/runtime-vapor/src/component.ts b/packages/runtime-vapor/src/component.ts
index 26a122647..4ad5e7f02 100644
--- a/packages/runtime-vapor/src/component.ts
+++ b/packages/runtime-vapor/src/component.ts
@@ -15,6 +15,7 @@ import {
currentInstance,
endMeasure,
expose,
+ isKeepAlive,
nextUid,
popWarningContext,
pushWarningContext,
@@ -151,6 +152,11 @@ export function createComponent(
locateHydrationNode()
}
+ if (currentInstance && isKeepAlive(currentInstance)) {
+ const cache = (currentInstance as KeepAliveInstance).getCache(component)
+ if (cache) return cache
+ }
+
// vdom interop enabled and component is not an explicit vapor component
if (appContext.vapor && !component.__vapor) {
const frag = appContext.vapor.vdomMount(
diff --git a/packages/runtime-vapor/src/components/KeepAlive.ts b/packages/runtime-vapor/src/components/KeepAlive.ts
index 6b7192c6b..f40a508a5 100644
--- a/packages/runtime-vapor/src/components/KeepAlive.ts
+++ b/packages/runtime-vapor/src/components/KeepAlive.ts
@@ -31,6 +31,7 @@ export interface KeepAliveInstance extends VaporComponentInstance {
) => void
deactivate: (instance: VaporComponentInstance) => void
process: (instance: VaporComponentInstance) => void
+ getCache: (comp: VaporComponent) => VaporComponentInstance | undefined
}
type CacheKey = PropertyKey | VaporComponent
@@ -103,6 +104,8 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
})
})
+ keepAliveInstance.getCache = (comp: VaporComponent) => cache.get(comp)
+
keepAliveInstance.process = (instance: VaporComponentInstance) => {
if (cache.has(instance.type)) {
instance.shapeFlag! |= ShapeFlags.COMPONENT_KEPT_ALIVE