]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(Transition): fix transition memory leak edge case (#12182)
authoredison <daiwei521@126.com>
Fri, 15 Nov 2024 02:40:26 +0000 (10:40 +0800)
committerGitHub <noreply@github.com>
Fri, 15 Nov 2024 02:40:26 +0000 (10:40 +0800)
close #12181

packages/runtime-core/src/components/BaseTransition.ts

index 6ce06d2823939febacf463ed0e3e6ad5f79213bc..2b58bc3fc43dbe201624271f1312b51d45623a4d 100644 (file)
@@ -198,8 +198,7 @@ const BaseTransitionImpl: ComponentOptions = {
         setTransitionHooks(innerChild, enterHooks)
       }
 
-      const oldChild = instance.subTree
-      const oldInnerChild = oldChild && getInnerChild(oldChild)
+      let oldInnerChild = instance.subTree && getInnerChild(instance.subTree)
 
       // handle mode
       if (
@@ -208,7 +207,7 @@ const BaseTransitionImpl: ComponentOptions = {
         !isSameVNodeType(innerChild, oldInnerChild) &&
         recursiveGetSubtree(instance).type !== Comment
       ) {
-        const leavingHooks = resolveTransitionHooks(
+        let leavingHooks = resolveTransitionHooks(
           oldInnerChild,
           rawProps,
           state,
@@ -228,6 +227,7 @@ const BaseTransitionImpl: ComponentOptions = {
               instance.update()
             }
             delete leavingHooks.afterLeave
+            oldInnerChild = undefined
           }
           return emptyPlaceholder(child)
         } else if (mode === 'in-out' && innerChild.type !== Comment) {
@@ -238,18 +238,27 @@ const BaseTransitionImpl: ComponentOptions = {
           ) => {
             const leavingVNodesCache = getLeavingNodesForType(
               state,
-              oldInnerChild,
+              oldInnerChild!,
             )
-            leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild
+            leavingVNodesCache[String(oldInnerChild!.key)] = oldInnerChild!
             // early removal callback
             el[leaveCbKey] = () => {
               earlyRemove()
               el[leaveCbKey] = undefined
               delete enterHooks.delayedLeave
+              oldInnerChild = undefined
+            }
+            enterHooks.delayedLeave = () => {
+              delayedLeave()
+              delete enterHooks.delayedLeave
+              oldInnerChild = undefined
             }
-            enterHooks.delayedLeave = delayedLeave
           }
+        } else {
+          oldInnerChild = undefined
         }
+      } else if (oldInnerChild) {
+        oldInnerChild = undefined
       }
 
       return child