Skip to content

Commit

Permalink
fix(runtime-core): fix edge case of KeepAlive inside Transition with …
Browse files Browse the repository at this point in the history
…slot children (vuejs#10719)

close vuejs#10708
  • Loading branch information
yangxiuxiu1115 authored and lynxlangya committed May 30, 2024
1 parent 5055b4a commit a91923d
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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()
})
})
32 changes: 22 additions & 10 deletions packages/runtime-core/src/components/BaseTransition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit a91923d

Please sign in to comment.