]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
chore: refactor
authordaiwei <daiwei521@126.com>
Thu, 10 Apr 2025 07:16:35 +0000 (15:16 +0800)
committerdaiwei <daiwei521@126.com>
Thu, 10 Apr 2025 07:29:59 +0000 (15:29 +0800)
packages/runtime-core/src/component.ts
packages/runtime-core/src/components/KeepAlive.ts
packages/runtime-vapor/src/apiTemplateRef.ts
packages/runtime-vapor/src/component.ts
packages/runtime-vapor/src/components/KeepAlive.ts

index f6ff8803c8742a536ce7ab1b7f501456e32d3611..be1a3e53182cd4de88bf01e492969fd459bef6d1 100644 (file)
@@ -196,6 +196,10 @@ export interface ComponentInternalOptions {
    * indicates vapor component
    */
   __vapor?: boolean
+  /**
+   * indicates keep-alive component
+   */
+  __isKeepAlive?: boolean
   /**
    * @internal
    */
index 89b0e83d5633d5892deb24e38720914fa577092c..eaa10e359df0d16ddf54df80e3e26713a1752b53 100644 (file)
@@ -456,7 +456,7 @@ function registerKeepAliveHook(
     let current = target.parent
     while (current && current.parent) {
       let parent = current.parent
-      if (isKeepAlive(parent.vapor ? (parent as any) : parent.vnode)) {
+      if (isKeepAlive(parent.vapor ? parent : parent.vnode)) {
         injectToKeepAliveRoot(wrappedHook, type, target, current)
       }
       current = current.parent
index 06a2c63af130485529b4b602cd699cffaaa4d780..fe4aca75eda0b15eecae4fbae69edb00c8fa4b7d 100644 (file)
@@ -50,11 +50,7 @@ export function setRef(
   if (!instance || instance.isUnmounted) return
 
   const setupState: any = __DEV__ ? instance.setupState || {} : null
-  const refValue = isVaporComponent(el)
-    ? getExposed(el) || el
-    : el instanceof DynamicFragment
-      ? getExposed(el.nodes as VaporComponentInstance) || el.nodes
-      : el
+  const refValue = getRefValue(el)
   const refs =
     instance.refs === EMPTY_OBJ ? (instance.refs = {}) : instance.refs
 
@@ -147,3 +143,12 @@ export function setRef(
   }
   return ref
 }
+
+const getRefValue = (el: RefEl) => {
+  if (isVaporComponent(el)) {
+    return getExposed(el) || el
+  } else if (el instanceof DynamicFragment) {
+    return getRefValue(el.nodes as RefEl)
+  }
+  return el
+}
index 4ad5e7f026da980e6090a1447e3fc5f12aedcb01..957ad1f99f123cd299c16a284b4ea0905610c4a3 100644 (file)
@@ -152,9 +152,12 @@ export function createComponent(
     locateHydrationNode()
   }
 
+  // try to get the cached instance if inside keep-alive
   if (currentInstance && isKeepAlive(currentInstance)) {
-    const cache = (currentInstance as KeepAliveInstance).getCache(component)
-    if (cache) return cache
+    const cached = (currentInstance as KeepAliveInstance).getCachedInstance(
+      component,
+    )
+    if (cached) return cached
   }
 
   // vdom interop enabled and component is not an explicit vapor component
@@ -525,7 +528,7 @@ export function mountComponent(
   }
   if (instance.bm) invokeArrayFns(instance.bm)
   insert(instance.block, parentNode, anchor)
-  if (instance.m) queuePostFlushCb(() => invokeArrayFns(instance.m!))
+  if (instance.m) queuePostFlushCb(instance.m!)
   if (
     instance.shapeFlag! & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE &&
     instance.a
@@ -558,7 +561,7 @@ export function unmountComponent(
     instance.scope.stop()
 
     if (instance.um) {
-      queuePostFlushCb(() => invokeArrayFns(instance.um!))
+      queuePostFlushCb(instance.um!)
     }
     instance.isUnmounted = true
   }
index 127f0c94f90907374c83f4a2fab30cf3d81e3ed2..6321ba50364035d9cc78a8241936aa9cc075d3a7 100644 (file)
@@ -12,13 +12,7 @@ import {
   warn,
   watch,
 } from '@vue/runtime-dom'
-import {
-  type Block,
-  DynamicFragment,
-  insert,
-  isFragment,
-  isValidBlock,
-} from '../block'
+import { type Block, insert, isFragment } from '../block'
 import {
   type ObjectVaporComponent,
   type VaporComponent,
@@ -37,16 +31,17 @@ export interface KeepAliveInstance extends VaporComponentInstance {
   ) => void
   deactivate: (instance: VaporComponentInstance) => void
   process: (instance: VaporComponentInstance) => void
-  getCache: (comp: VaporComponent) => VaporComponentInstance | undefined
+  getCachedInstance: (
+    comp: VaporComponent,
+  ) => VaporComponentInstance | undefined
 }
 
-type CacheKey = PropertyKey | VaporComponent
+type CacheKey = VaporComponent
 type Cache = Map<CacheKey, VaporComponentInstance>
 type Keys = Set<CacheKey>
 
 export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
   name: 'VaporKeepAlive',
-  // @ts-expect-error
   __isKeepAlive: true,
   props: {
     include: [String, RegExp, Array],
@@ -80,13 +75,10 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
     function cacheBlock() {
       const { max } = props
       // TODO suspense
-      const currentBlock = keepAliveInstance.block!
-      if (!isValidBlock(currentBlock)) return
-
-      const block = getInnerBlock(currentBlock)!
-      if (!block || !shouldCache(block)) return
+      const innerBlock = getInnerBlock(keepAliveInstance.block!)!
+      if (!innerBlock || !shouldCache(innerBlock)) return
 
-      const key = block.type
+      const key = innerBlock.type
       if (cache.has(key)) {
         // make this key the freshest
         keys.delete(key)
@@ -98,7 +90,7 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
           pruneCacheEntry(keys.values().next().value!)
         }
       }
-      cache.set(key, (current = block))
+      cache.set(key, (current = innerBlock))
     }
 
     onMounted(cacheBlock)
@@ -118,9 +110,12 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
       })
     })
 
-    keepAliveInstance.getCache = (comp: VaporComponent) => cache.get(comp)
+    keepAliveInstance.getCachedInstance = (comp: VaporComponent) =>
+      cache.get(comp)
 
-    keepAliveInstance.process = (instance: VaporComponentInstance) => {
+    const process = (keepAliveInstance.process = (
+      instance: VaporComponentInstance,
+    ) => {
       if (cache.has(instance.type)) {
         instance.shapeFlag! |= ShapeFlags.COMPONENT_KEPT_ALIVE
       }
@@ -128,15 +123,15 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
       if (shouldCache(instance)) {
         instance.shapeFlag! |= ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE
       }
-    }
+    })
 
     keepAliveInstance.activate = (
       instance: VaporComponentInstance,
       parentNode: ParentNode,
       anchor: Node,
     ) => {
-      const cachedBlock = (current = cache.get(instance.type)!)
-      insert((instance.block = cachedBlock.block), parentNode, anchor)
+      current = instance
+      insert(instance.block, parentNode, anchor)
       queuePostFlushCb(() => {
         instance.isDeactivated = false
         if (instance.a) invokeArrayFns(instance.a)
@@ -167,12 +162,11 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
       return children
     }
 
-    // wrap children in dynamic fragment
-    if (!isFragment(children)) {
-      const frag = new DynamicFragment()
-      frag.update(() => children)
-      children = frag
-    }
+    // `children` could be either a `VaporComponentInstance` or a `DynamicFragment`
+    // (when using `v-if` or `<component is/>`). For `DynamicFragment` children,
+    // the `shapeFlag` is processed in `DynamicFragment.update`. Here only need
+    // to process the `VaporComponentInstance`
+    if (isVaporComponent(children)) process(children)
 
     function pruneCache(filter: (name: string) => boolean) {
       cache.forEach((instance, key) => {
@@ -187,6 +181,7 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
       const cached = cache.get(key)
       if (cached) {
         resetShapeFlag(cached)
+        // don't unmount if the instance is the current one
         if (cached !== current) {
           unmountComponent(cached)
         }