wip: refactor

This commit is contained in:
daiwei 2025-04-09 21:19:29 +08:00
parent dccc47c265
commit 1c5d833a76
4 changed files with 46 additions and 35 deletions

View 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])
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
// 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
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 = 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 = 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 = 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
})
})

View 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)

View 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(

View 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