fix(runtime-core): fix edge case of KeepAlive inside Transition with slot children (#10719)

close #10708
This commit is contained in:
yangxiuxiu 2024-04-18 12:00:06 +08:00 committed by GitHub
parent 70641fc0de
commit e51ca61ca0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 10 deletions

View File

@ -1230,4 +1230,9 @@ describe('BaseTransition', () => {
await runTestWithKeepAlive(testInOutBeforeFinish) await runTestWithKeepAlive(testInOutBeforeFinish)
}) })
}) })
// #10719
test('should not error on KeepAlive w/ function children', () => {
expect(() => mount({}, () => () => h('div'), true)).not.toThrow()
})
}) })

View File

@ -16,7 +16,7 @@ import { warn } from '../warning'
import { isKeepAlive } from './KeepAlive' import { isKeepAlive } from './KeepAlive'
import { toRaw } from '@vue/reactivity' import { toRaw } from '@vue/reactivity'
import { ErrorCodes, callWithAsyncErrorHandling } from '../errorHandling' 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 { onBeforeUnmount, onMounted } from '../apiLifecycle'
import type { RendererElement } from '../renderer' import type { RendererElement } from '../renderer'
@ -459,15 +459,27 @@ function emptyPlaceholder(vnode: VNode): VNode | undefined {
} }
function getKeepAliveChild(vnode: VNode): VNode | undefined { function getKeepAliveChild(vnode: VNode): VNode | undefined {
return isKeepAlive(vnode) if (!isKeepAlive(vnode)) {
? // #7121 ensure get the child component subtree in case return vnode
// it's been replaced during HMR }
__DEV__ && vnode.component // #7121 ensure get the child component subtree in case
? vnode.component.subTree // it's been replaced during HMR
: vnode.children if (__DEV__ && vnode.component) {
? ((vnode.children as VNodeArrayChildren)[0] as VNode) return vnode.component.subTree
: undefined }
: vnode
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) { export function setTransitionHooks(vnode: VNode, hooks: TransitionHooks) {