|
|
@@ -9,7 +9,6 @@ import {
|
|
|
devtoolsComponentAdded,
|
|
|
getComponentName,
|
|
|
isAsyncWrapper,
|
|
|
- isKeepAlive,
|
|
|
matches,
|
|
|
onBeforeUnmount,
|
|
|
onMounted,
|
|
|
@@ -38,16 +37,19 @@ import {
|
|
|
import type { EffectScope } from '@vue/reactivity'
|
|
|
|
|
|
export interface KeepAliveInstance extends VaporComponentInstance {
|
|
|
- activate: (
|
|
|
- instance: VaporComponentInstance,
|
|
|
- parentNode: ParentNode,
|
|
|
- anchor?: Node | null | 0,
|
|
|
- ) => void
|
|
|
- deactivate: (instance: VaporComponentInstance) => void
|
|
|
- getCachedComponent: (
|
|
|
- comp: VaporComponent,
|
|
|
- ) => VaporComponentInstance | VaporFragment | undefined
|
|
|
- getStorageContainer: () => ParentNode
|
|
|
+ ctx: {
|
|
|
+ activate: (
|
|
|
+ instance: VaporComponentInstance,
|
|
|
+ parentNode: ParentNode,
|
|
|
+ anchor?: Node | null | 0,
|
|
|
+ ) => void
|
|
|
+ deactivate: (instance: VaporComponentInstance) => void
|
|
|
+ getCachedComponent: (
|
|
|
+ comp: VaporComponent,
|
|
|
+ ) => VaporComponentInstance | VaporFragment | undefined
|
|
|
+ getStorageContainer: () => ParentNode
|
|
|
+ onAsyncResolve: (asyncWrapper: VaporComponentInstance) => void
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
type CacheKey = VaporComponent | VNode['type']
|
|
|
@@ -78,18 +80,24 @@ const KeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
|
|
|
;(keepAliveInstance as any).__v_cache = cache
|
|
|
}
|
|
|
|
|
|
- keepAliveInstance.getStorageContainer = () => storageContainer
|
|
|
-
|
|
|
- keepAliveInstance.getCachedComponent = comp => cache.get(comp)
|
|
|
-
|
|
|
- keepAliveInstance.activate = (instance, parentNode, anchor) => {
|
|
|
- current = instance
|
|
|
- activate(instance, parentNode, anchor)
|
|
|
- }
|
|
|
-
|
|
|
- keepAliveInstance.deactivate = instance => {
|
|
|
- current = undefined
|
|
|
- deactivate(instance, storageContainer)
|
|
|
+ keepAliveInstance.ctx = {
|
|
|
+ getStorageContainer: () => storageContainer,
|
|
|
+ getCachedComponent: comp => cache.get(comp),
|
|
|
+ activate: (instance, parentNode, anchor) => {
|
|
|
+ current = instance
|
|
|
+ activate(instance, parentNode, anchor)
|
|
|
+ },
|
|
|
+ deactivate: instance => {
|
|
|
+ current = undefined
|
|
|
+ deactivate(instance, storageContainer)
|
|
|
+ },
|
|
|
+ // called when async component resolves to evaluate caching
|
|
|
+ onAsyncResolve: (asyncWrapper: VaporComponentInstance) => {
|
|
|
+ if (shouldCache(asyncWrapper, props, false)) {
|
|
|
+ asyncWrapper.shapeFlag! |= ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE
|
|
|
+ innerCacheBlock(asyncWrapper.type, asyncWrapper)
|
|
|
+ }
|
|
|
+ },
|
|
|
}
|
|
|
|
|
|
const innerCacheBlock = (
|
|
|
@@ -293,9 +301,10 @@ const shouldCache = (
|
|
|
: (block as GenericComponentInstance).type
|
|
|
) as GenericComponent & AsyncComponentInternalOptions
|
|
|
|
|
|
- // return true to ensure hooks are injected into its block (DynamicFragment)
|
|
|
+ // for unresolved async components, don't cache yet
|
|
|
+ // caching will be done in onAsyncResolve after the component resolves
|
|
|
if (isAsync && !type.__asyncResolved) {
|
|
|
- return true
|
|
|
+ return false
|
|
|
}
|
|
|
|
|
|
const { include, exclude } = props
|
|
|
@@ -378,16 +387,3 @@ export function deactivate(
|
|
|
devtoolsComponentAdded(instance)
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-export function findParentKeepAlive(
|
|
|
- instance: VaporComponentInstance,
|
|
|
-): KeepAliveInstance | null {
|
|
|
- let parent = instance as GenericComponentInstance | null
|
|
|
- while (parent) {
|
|
|
- if (isKeepAlive(parent)) {
|
|
|
- return parent as KeepAliveInstance
|
|
|
- }
|
|
|
- parent = parent.parent
|
|
|
- }
|
|
|
- return null
|
|
|
-}
|