Skip to content

Commit fec12d7

Browse files
authored
fix(runtime-core): transition hooks can be arrays of functions (#5177)
1 parent da10dd7 commit fec12d7

File tree

1 file changed

+33
-24
lines changed

1 file changed

+33
-24
lines changed

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

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

23+
type Hook<T = () => void> = T | T[]
24+
2325
export interface BaseTransitionProps<HostElement = RendererElement> {
2426
mode?: 'in-out' | 'out-in' | 'default'
2527
appear?: boolean
@@ -34,20 +36,20 @@ export interface BaseTransitionProps<HostElement = RendererElement> {
3436
// Hooks. Using camel case for easier usage in render functions & JSX.
3537
// In templates these can be written as @before-enter="xxx" as prop names
3638
// are camelized.
37-
onBeforeEnter?: (el: HostElement) => void
38-
onEnter?: (el: HostElement, done: () => void) => void
39-
onAfterEnter?: (el: HostElement) => void
40-
onEnterCancelled?: (el: HostElement) => void
39+
onBeforeEnter?: Hook<(el: HostElement) => void>
40+
onEnter?: Hook<(el: HostElement, done: () => void) => void>
41+
onAfterEnter?: Hook<(el: HostElement) => void>
42+
onEnterCancelled?: Hook<(el: HostElement) => void>
4143
// leave
42-
onBeforeLeave?: (el: HostElement) => void
43-
onLeave?: (el: HostElement, done: () => void) => void
44-
onAfterLeave?: (el: HostElement) => void
45-
onLeaveCancelled?: (el: HostElement) => void // only fired in persisted mode
44+
onBeforeLeave?: Hook<(el: HostElement) => void>
45+
onLeave?: Hook<(el: HostElement, done: () => void) => void>
46+
onAfterLeave?: Hook<(el: HostElement) => void>
47+
onLeaveCancelled?: Hook<(el: HostElement) => void> // only fired in persisted mode
4648
// appear
47-
onBeforeAppear?: (el: HostElement) => void
48-
onAppear?: (el: HostElement, done: () => void) => void
49-
onAfterAppear?: (el: HostElement) => void
50-
onAppearCancelled?: (el: HostElement) => void
49+
onBeforeAppear?: Hook<(el: HostElement) => void>
50+
onAppear?: Hook<(el: HostElement, done: () => void) => void>
51+
onAfterAppear?: Hook<(el: HostElement) => void>
52+
onAppearCancelled?: Hook<(el: HostElement) => void>
5153
}
5254

5355
export interface TransitionHooks<
@@ -69,9 +71,9 @@ export interface TransitionHooks<
6971
delayedLeave?(): void
7072
}
7173

72-
export type TransitionHookCaller = (
73-
hook: ((el: any) => void) | Array<(el: any) => void> | undefined,
74-
args?: any[]
74+
export type TransitionHookCaller = <T extends any[] = [el: any]>(
75+
hook: Hook<(...args: T) => void> | undefined,
76+
args?: T
7577
) => void
7678

7779
export type PendingCallback = (cancelled?: boolean) => void
@@ -331,6 +333,19 @@ export function resolveTransitionHooks(
331333
)
332334
}
333335

336+
const callAsyncHook = (
337+
hook: Hook<(el: any, done: () => void) => void>,
338+
args: [TransitionElement, () => void]
339+
) => {
340+
const done = args[1]
341+
callHook(hook, args)
342+
if (isArray(hook)) {
343+
if (hook.every(hook => hook.length <= 1)) done()
344+
} else if (hook.length <= 1) {
345+
done()
346+
}
347+
}
348+
334349
const hooks: TransitionHooks<TransitionElement> = {
335350
mode,
336351
persisted,
@@ -388,10 +403,7 @@ export function resolveTransitionHooks(
388403
el._enterCb = undefined
389404
})
390405
if (hook) {
391-
hook(el, done)
392-
if (hook.length <= 1) {
393-
done()
394-
}
406+
callAsyncHook(hook, [el, done])
395407
} else {
396408
done()
397409
}
@@ -423,10 +435,7 @@ export function resolveTransitionHooks(
423435
})
424436
leavingVNodesCache[key] = vnode
425437
if (onLeave) {
426-
onLeave(el, done)
427-
if (onLeave.length <= 1) {
428-
done()
429-
}
438+
callAsyncHook(onLeave, [el, done])
430439
} else {
431440
done()
432441
}

0 commit comments

Comments
 (0)