Przeglądaj źródła

fix(Transition): fix transition memory leak edge case (#12182)

close #12181
edison 1 rok temu
rodzic
commit
660132df6c

+ 15 - 6
packages/runtime-core/src/components/BaseTransition.ts

@@ -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