Skip to content

Commit e51ca61

Browse files
authoredApr 18, 2024··
fix(runtime-core): fix edge case of KeepAlive inside Transition with slot children (#10719)
close #10708
1 parent 70641fc commit e51ca61

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed
 

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

+5
Original file line numberDiff line numberDiff line change
@@ -1230,4 +1230,9 @@ describe('BaseTransition', () => {
12301230
await runTestWithKeepAlive(testInOutBeforeFinish)
12311231
})
12321232
})
1233+
1234+
// #10719
1235+
test('should not error on KeepAlive w/ function children', () => {
1236+
expect(() => mount({}, () => () => h('div'), true)).not.toThrow()
1237+
})
12331238
})

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

+22-10
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { warn } from '../warning'
1616
import { isKeepAlive } from './KeepAlive'
1717
import { toRaw } from '@vue/reactivity'
1818
import { ErrorCodes, callWithAsyncErrorHandling } from '../errorHandling'
19-
import { PatchFlags, ShapeFlags, isArray } from '@vue/shared'
19+
import { PatchFlags, ShapeFlags, isArray, isFunction } from '@vue/shared'
2020
import { onBeforeUnmount, onMounted } from '../apiLifecycle'
2121
import type { RendererElement } from '../renderer'
2222

@@ -459,15 +459,27 @@ function emptyPlaceholder(vnode: VNode): VNode | undefined {
459459
}
460460

461461
function getKeepAliveChild(vnode: VNode): VNode | undefined {
462-
return isKeepAlive(vnode)
463-
? // #7121 ensure get the child component subtree in case
464-
// it's been replaced during HMR
465-
__DEV__ && vnode.component
466-
? vnode.component.subTree
467-
: vnode.children
468-
? ((vnode.children as VNodeArrayChildren)[0] as VNode)
469-
: undefined
470-
: vnode
462+
if (!isKeepAlive(vnode)) {
463+
return vnode
464+
}
465+
// #7121 ensure get the child component subtree in case
466+
// it's been replaced during HMR
467+
if (__DEV__ && vnode.component) {
468+
return vnode.component.subTree
469+
}
470+
471+
const { shapeFlag, children } = vnode
472+
473+
if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
474+
return (children as VNodeArrayChildren)[0] as VNode
Has a conversation. Original line has a conversation.
475+
}
476+
477+
if (
478+
shapeFlag & ShapeFlags.SLOTS_CHILDREN &&
479+
isFunction((children as any).default)
480+
) {
481+
return (children as any).default()
482+
}
471483
}
472484

473485
export function setTransitionHooks(vnode: VNode, hooks: TransitionHooks) {

0 commit comments

Comments
 (0)
Please sign in to comment.