]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: refactor
authordaiwei <daiwei521@126.com>
Wed, 9 Apr 2025 13:19:29 +0000 (21:19 +0800)
committerdaiwei <daiwei521@126.com>
Wed, 9 Apr 2025 13:19:29 +0000 (21:19 +0800)
packages/runtime-vapor/__tests__/components/KeepAlive.spec.ts
packages/runtime-vapor/src/block.ts
packages/runtime-vapor/src/component.ts
packages/runtime-vapor/src/components/KeepAlive.ts

index ea1ee8527a5bac21e0d0aea8f602175655022203..4cd8727f009e6bdc0112ad1bb41b65dab366084e 100644 (file)
@@ -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(`<!--if-->`)
-    // 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(`<!--if-->`)
-    // 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(`<!--if-->`)
-    // 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(`<div>two</div><!--if--><!--if-->`)
-    // 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(`<!--if-->`)
-    // assertHookCalls(oneHooks, [1, 1, 3, 3, 0])
-    // // assertHookCalls(twoHooks, [1, 1, 4, 4, 0])
-
-    // toggle1.value = true
-    // await nextTick()
-    // expect(html()).toBe(`<!--if--><!--if-->`)
-    // assertHookCalls(oneHooks, [1, 1, 4, 3, 0])
-    // // assertHookCalls(twoHooks, [1, 1, 4, 4, 0]) // should remain inactive
+    toggle1.value = false
+    await nextTick()
+    expect(html()).toBe(`<!--if-->`)
+    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(`<!--if-->`)
+    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(`<!--if-->`)
+    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(`<div>two</div><!--if--><!--if-->`)
+    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(`<!--if-->`)
+    assertHookCalls(oneHooks, [1, 1, 3, 3, 0])
+    assertHookCalls(twoHooks, [1, 1, 4, 4, 0])
+
+    toggle1.value = true
+    await nextTick()
+    expect(html()).toBe(`<!--if--><!--if-->`)
+    assertHookCalls(oneHooks, [1, 1, 4, 3, 0])
+    assertHookCalls(twoHooks, [1, 1, 4, 4, 0]) // should remain inactive
   })
 })
index c93e94612a68a542fd8cfcc43bc34dc4c28002f1..c9d81986b45bab3d600e9ccbcbadfcd3c20b9adb 100644 (file)
@@ -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)
index 26a1226477f155d203a7c5812b2a37fee6aca110..4ad5e7f026da980e6090a1447e3fc5f12aedcb01 100644 (file)
@@ -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(
index 6b7192c6bd8bfe4b876404ae3e2819cde98a2fb0..f40a508a57a2830176c4cfc215c574b1374f17a9 100644 (file)
@@ -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