Răsfoiți Sursa

refactor(runtime-vapor): move KeepAlive branch caching to update hook

daiwei 2 săptămâni în urmă
părinte
comite
2a52f6e22a

+ 1 - 1
packages/runtime-vapor/src/component.ts

@@ -1334,7 +1334,7 @@ function registerDynamicFragmentFallthroughAttrs(
   attrs: Record<string, any>,
 ): void {
   frag.hasFallthroughAttrs = true
-  ;(frag.onBeforeInsert || (frag.onBeforeInsert = [])).push(nodes => {
+  ;(frag.onBeforeInsert ||= []).push(nodes => {
     if (nodes instanceof Element) {
       // ensure render effect is cleaned up when branch scope is stopped
       frag.scope!.run(() => {

+ 18 - 0
packages/runtime-vapor/src/components/KeepAlive.ts

@@ -384,9 +384,13 @@ const VaporKeepAliveImpl = defineVaporComponent({
     const prevCtx = setCurrentKeepAliveCtx(keepAliveCtx)
     let children = slots.default()
     setCurrentKeepAliveCtx(prevCtx)
+    registerDynamicFragmentUpdated(children, cacheBlock)
 
     if (isArray(children)) {
       children = children.filter(child => !(child instanceof Comment))
+      if (children.length === 1) {
+        registerDynamicFragmentUpdated(children[0], cacheBlock)
+      }
       if (children.length > 1) {
         if (__DEV__) {
           warn(`KeepAlive should contain exactly one component child.`)
@@ -402,6 +406,20 @@ const VaporKeepAliveImpl = defineVaporComponent({
 export const VaporKeepAlive: DefineVaporComponent<{}, string, KeepAliveProps> =
   /*@__PURE__*/ withKeepAliveEnabled(VaporKeepAliveImpl)
 
+function registerDynamicFragmentUpdated(
+  block: Block,
+  cacheBlock: (block?: Block) => void,
+): void {
+  if (!isDynamicFragment(block)) return
+  ;(block.onUpdated ||= []).unshift(() => {
+    if (block.$transition && block.$transition.mode === 'out-in') {
+      // For out-in transition, call cacheBlock after renderBranch completes
+      // because KeepAlive's onUpdated fires before the deferred rendering finishes.
+      cacheBlock(block)
+    }
+  })
+}
+
 const shouldCache = (
   block: GenericComponentInstance | VaporFragment,
   props: KeepAliveProps,

+ 5 - 8
packages/runtime-vapor/src/fragment.ts

@@ -472,20 +472,17 @@ export class DynamicFragment extends VaporFragment {
           onBeforeInsert.forEach(hook => hook(this.nodes))
         }
         insert(this.nodes, parent, this.anchor)
-
-        // For out-in transition, call cacheBlock after renderBranch completes
-        // because KeepAlive's onUpdated fires before the deferred rendering finishes
-        if (keepAliveCtx && transition && transition.mode === 'out-in') {
-          keepAliveCtx.cacheBlock()
-        }
       }
     } else {
       this.scope = undefined
       this.nodes = EMPTY_BLOCK
     }
 
-    if (parent && this.onUpdated) {
-      this.onUpdated.forEach(hook => hook(this.nodes))
+    if (parent) {
+      const onUpdated = this.onUpdated
+      if (onUpdated) {
+        onUpdated.forEach(hook => hook(this.nodes))
+      }
     }
   }