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) 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 toggle2 = ref(true)
const one = defineVaporComponent({ const one = defineVaporComponent({
name: 'one', name: 'one',
@ -431,42 +431,42 @@ describe('VaporKeepAlive', () => {
// the activated hook of two is not called // the activated hook of two is not called
assertHookCalls(twoHooks, [1, 1, 3, 2, 0]) assertHookCalls(twoHooks, [1, 1, 3, 2, 0])
// toggle1.value = false toggle1.value = false
// await nextTick() await nextTick()
// expect(html()).toBe(`<!--if-->`) expect(html()).toBe(`<!--if-->`)
// assertHookCalls(oneHooks, [1, 1, 2, 2, 0]) assertHookCalls(oneHooks, [1, 1, 2, 2, 0])
// assertHookCalls(twoHooks, [1, 1, 3, 3, 0]) assertHookCalls(twoHooks, [1, 1, 3, 3, 0])
// // toggle nested instance when parent is deactivated // toggle nested instance when parent is deactivated
// toggle2.value = false toggle2.value = false
// await nextTick() await nextTick()
// expect(html()).toBe(`<!--if-->`) expect(html()).toBe(`<!--if-->`)
// assertHookCalls(oneHooks, [1, 1, 2, 2, 0]) assertHookCalls(oneHooks, [1, 1, 2, 2, 0])
// // assertHookCalls(twoHooks, [1, 1, 3, 3, 0]) // should not be affected assertHookCalls(twoHooks, [1, 1, 3, 3, 0]) // should not be affected
// toggle2.value = true toggle2.value = true
// await nextTick() await nextTick()
// expect(html()).toBe(`<!--if-->`) expect(html()).toBe(`<!--if-->`)
// assertHookCalls(oneHooks, [1, 1, 2, 2, 0]) assertHookCalls(oneHooks, [1, 1, 2, 2, 0])
// // assertHookCalls(twoHooks, [1, 1, 3, 3, 0]) // should not be affected assertHookCalls(twoHooks, [1, 1, 3, 3, 0]) // should not be affected
// toggle1.value = true toggle1.value = true
// await nextTick() await nextTick()
// expect(html()).toBe(`<div>two</div><!--if--><!--if-->`) expect(html()).toBe(`<div>two</div><!--if--><!--if-->`)
// assertHookCalls(oneHooks, [1, 1, 3, 2, 0]) assertHookCalls(oneHooks, [1, 1, 3, 2, 0])
// // assertHookCalls(twoHooks, [1, 1, 4, 3, 0]) assertHookCalls(twoHooks, [1, 1, 4, 3, 0])
// toggle1.value = false toggle1.value = false
// toggle2.value = false toggle2.value = false
// await nextTick() await nextTick()
// expect(html()).toBe(`<!--if-->`) expect(html()).toBe(`<!--if-->`)
// assertHookCalls(oneHooks, [1, 1, 3, 3, 0]) assertHookCalls(oneHooks, [1, 1, 3, 3, 0])
// // assertHookCalls(twoHooks, [1, 1, 4, 4, 0]) assertHookCalls(twoHooks, [1, 1, 4, 4, 0])
// toggle1.value = true toggle1.value = true
// await nextTick() await nextTick()
// expect(html()).toBe(`<!--if--><!--if-->`) expect(html()).toBe(`<!--if--><!--if-->`)
// assertHookCalls(oneHooks, [1, 1, 4, 3, 0]) assertHookCalls(oneHooks, [1, 1, 4, 3, 0])
// // assertHookCalls(twoHooks, [1, 1, 4, 4, 0]) // should remain inactive 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( ;(instance as KeepAliveInstance).process(
this.nodes as VaporComponentInstance, this.nodes as VaporComponentInstance,
) )
} unmountComponent(this.nodes as VaporComponentInstance)
} else {
this.scope.stop() this.scope.stop()
}
parent && remove(this.nodes, parent) parent && remove(this.nodes, parent)
} }
@ -128,7 +130,7 @@ export function insert(
parent.insertBefore(block, anchor) parent.insertBefore(block, anchor)
} }
} else if (isVaporComponent(block)) { } else if (isVaporComponent(block)) {
if (block.isMounted) { if (block.isMounted && !block.isDeactivated) {
insert(block.block!, parent, anchor) insert(block.block!, parent, anchor)
} else { } else {
mountComponent(block, parent, anchor) mountComponent(block, parent, anchor)

View File

@ -15,6 +15,7 @@ import {
currentInstance, currentInstance,
endMeasure, endMeasure,
expose, expose,
isKeepAlive,
nextUid, nextUid,
popWarningContext, popWarningContext,
pushWarningContext, pushWarningContext,
@ -151,6 +152,11 @@ export function createComponent(
locateHydrationNode() 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 // vdom interop enabled and component is not an explicit vapor component
if (appContext.vapor && !component.__vapor) { if (appContext.vapor && !component.__vapor) {
const frag = appContext.vapor.vdomMount( const frag = appContext.vapor.vdomMount(

View File

@ -31,6 +31,7 @@ export interface KeepAliveInstance extends VaporComponentInstance {
) => void ) => void
deactivate: (instance: VaporComponentInstance) => void deactivate: (instance: VaporComponentInstance) => void
process: (instance: VaporComponentInstance) => void process: (instance: VaporComponentInstance) => void
getCache: (comp: VaporComponent) => VaporComponentInstance | undefined
} }
type CacheKey = PropertyKey | VaporComponent type CacheKey = PropertyKey | VaporComponent
@ -103,6 +104,8 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
}) })
}) })
keepAliveInstance.getCache = (comp: VaporComponent) => cache.get(comp)
keepAliveInstance.process = (instance: VaporComponentInstance) => { keepAliveInstance.process = (instance: VaporComponentInstance) => {
if (cache.has(instance.type)) { if (cache.has(instance.type)) {
instance.shapeFlag! |= ShapeFlags.COMPONENT_KEPT_ALIVE instance.shapeFlag! |= ShapeFlags.COMPONENT_KEPT_ALIVE