]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(transition): fix KeepAlive with transition out-in mode behavior in production...
authoryangxiuxiu <79584569+yangxiuxiu1115@users.noreply.github.com>
Tue, 13 May 2025 14:16:45 +0000 (22:16 +0800)
committerGitHub <noreply@github.com>
Tue, 13 May 2025 14:16:45 +0000 (22:16 +0800)
close #12465

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

index aaeae3fb4f05e6f62dc1f8705b07a73eb2ce0adc..b40113fb5b8f820b213307dd338d60b62c708097 100644 (file)
@@ -1198,4 +1198,51 @@ describe('BaseTransition', () => {
   test('should not error on KeepAlive w/ function children', () => {
     expect(() => mount({}, () => () => h('div'), true)).not.toThrow()
   })
+
+  // #12465
+  test('mode: "out-in" w/ KeepAlive + fallthrough attrs (prod mode)', async () => {
+    __DEV__ = false
+    async function testOutIn({ trueBranch, falseBranch }: ToggleOptions) {
+      const toggle = ref(true)
+      const { props, cbs } = mockProps({ mode: 'out-in' }, true)
+      const root = nodeOps.createElement('div')
+      const App = {
+        render() {
+          return h(
+            BaseTransition,
+            {
+              ...props,
+              class: 'test',
+            },
+            () =>
+              h(KeepAlive, null, toggle.value ? trueBranch() : falseBranch()),
+          )
+        },
+      }
+      render(h(App), root)
+
+      expect(serializeInner(root)).toBe(`<div class="test">0</div>`)
+
+      // trigger toggle
+      toggle.value = false
+      await nextTick()
+      expect(props.onBeforeLeave).toHaveBeenCalledTimes(1)
+      expect(serialize((props.onBeforeLeave as any).mock.calls[0][0])).toBe(
+        `<div class="test">0</div>`,
+      )
+      expect(props.onLeave).toHaveBeenCalledTimes(1)
+      expect(serialize((props.onLeave as any).mock.calls[0][0])).toBe(
+        `<div class="test">0</div>`,
+      )
+      expect(props.onAfterLeave).not.toHaveBeenCalled()
+      // enter should not have started
+      expect(props.onBeforeEnter).not.toHaveBeenCalled()
+      expect(props.onEnter).not.toHaveBeenCalled()
+      expect(props.onAfterEnter).not.toHaveBeenCalled()
+      cbs.doneLeave[`<div class="test">0</div>`]()
+      expect(serializeInner(root)).toBe(`<span class="test">0</span>`)
+    }
+    await runTestWithKeepAlive(testOutIn)
+    __DEV__ = true
+  })
 })
index 2b58bc3fc43dbe201624271f1312b51d45623a4d..fbb449ec8cb1c7cca3a65c3672297bd098b1a6ab 100644 (file)
@@ -501,9 +501,8 @@ function getInnerChild(vnode: VNode): VNode | undefined {
 
     return vnode
   }
-  // #7121 ensure get the child component subtree in case
-  // it's been replaced during HMR
-  if (__DEV__ && vnode.component) {
+  // #7121,#12465 get the component subtree if it's been mounted
+  if (vnode.component) {
     return vnode.component.subTree
   }