]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-core): fix edge case of KeepAlive inside Transition with slot children...
authoryangxiuxiu <79584569+yangxiuxiu1115@users.noreply.github.com>
Thu, 18 Apr 2024 04:00:06 +0000 (12:00 +0800)
committerGitHub <noreply@github.com>
Thu, 18 Apr 2024 04:00:06 +0000 (12:00 +0800)
close #10708

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

index 3184c9c9c6a8a5741a370c1ea39816cd9f073dc7..1923d1618978427c5cd203b1d60e85816c7acab5 100644 (file)
@@ -1230,4 +1230,9 @@ describe('BaseTransition', () => {
       await runTestWithKeepAlive(testInOutBeforeFinish)
     })
   })
+
+  // #10719
+  test('should not error on KeepAlive w/ function children', () => {
+    expect(() => mount({}, () => () => h('div'), true)).not.toThrow()
+  })
 })
index e99fe0e496c699d87ec8155dbf3041eefd99b0a0..5d41751285bf5c6ee7fbd0a0b2e02d51e31f25a2 100644 (file)
@@ -16,7 +16,7 @@ import { warn } from '../warning'
 import { isKeepAlive } from './KeepAlive'
 import { toRaw } from '@vue/reactivity'
 import { ErrorCodes, callWithAsyncErrorHandling } from '../errorHandling'
-import { PatchFlags, ShapeFlags, isArray } from '@vue/shared'
+import { PatchFlags, ShapeFlags, isArray, isFunction } from '@vue/shared'
 import { onBeforeUnmount, onMounted } from '../apiLifecycle'
 import type { RendererElement } from '../renderer'
 
@@ -459,15 +459,27 @@ function emptyPlaceholder(vnode: VNode): VNode | undefined {
 }
 
 function getKeepAliveChild(vnode: VNode): VNode | undefined {
-  return isKeepAlive(vnode)
-    ? // #7121 ensure get the child component subtree in case
-      // it's been replaced during HMR
-      __DEV__ && vnode.component
-      ? vnode.component.subTree
-      : vnode.children
-        ? ((vnode.children as VNodeArrayChildren)[0] as VNode)
-        : undefined
-    : vnode
+  if (!isKeepAlive(vnode)) {
+    return vnode
+  }
+  // #7121 ensure get the child component subtree in case
+  // it's been replaced during HMR
+  if (__DEV__ && vnode.component) {
+    return vnode.component.subTree
+  }
+
+  const { shapeFlag, children } = vnode
+
+  if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
+    return (children as VNodeArrayChildren)[0] as VNode
+  }
+
+  if (
+    shapeFlag & ShapeFlags.SLOTS_CHILDREN &&
+    isFunction((children as any).default)
+  ) {
+    return (children as any).default()
+  }
 }
 
 export function setTransitionHooks(vnode: VNode, hooks: TransitionHooks) {