fix(transition): fix dom transition cancel hooks not being called

This commit is contained in:
Evan You 2020-06-25 15:00:59 -04:00
parent b3bdd7046f
commit acd3156d2c
2 changed files with 35 additions and 16 deletions

View File

@ -99,7 +99,14 @@ export function resolveTransitionProps(
const durations = normalizeDuration(duration) const durations = normalizeDuration(duration)
const enterDuration = durations && durations[0] const enterDuration = durations && durations[0]
const leaveDuration = durations && durations[1] const leaveDuration = durations && durations[1]
const { appear, onBeforeEnter, onEnter, onLeave } = baseProps const {
appear,
onBeforeEnter,
onEnter,
onLeave,
onEnterCancelled,
onLeaveCancelled
} = baseProps
// is appearing // is appearing
if (appear && !instance.isMounted) { if (appear && !instance.isMounted) {
@ -108,9 +115,11 @@ export function resolveTransitionProps(
enterToClass = appearToClass enterToClass = appearToClass
} }
type Hook = (el: Element, done?: () => void) => void type Hook =
| ((el: Element, done: () => void) => void)
| ((el: Element) => void)
const finishEnter: Hook = (el, done) => { const finishEnter = (el: Element, done?: () => void) => {
removeTransitionClass(el, enterToClass) removeTransitionClass(el, enterToClass)
removeTransitionClass(el, enterActiveClass) removeTransitionClass(el, enterActiveClass)
done && done() done && done()
@ -120,7 +129,7 @@ export function resolveTransitionProps(
} }
} }
const finishLeave: Hook = (el, done) => { const finishLeave = (el: Element, done?: () => void) => {
removeTransitionClass(el, leaveToClass) removeTransitionClass(el, leaveToClass)
removeTransitionClass(el, leaveActiveClass) removeTransitionClass(el, leaveActiveClass)
done && done() done && done()
@ -128,8 +137,14 @@ export function resolveTransitionProps(
// only needed for user hooks called in nextFrame // only needed for user hooks called in nextFrame
// sync errors are already handled by BaseTransition // sync errors are already handled by BaseTransition
function callHookWithErrorHandling(hook: Hook, args: any[]) { const callHook = (hook: Hook | undefined, args: any[]) => {
callWithAsyncErrorHandling(hook, instance, ErrorCodes.TRANSITION_HOOK, args) hook &&
callWithAsyncErrorHandling(
hook,
instance,
ErrorCodes.TRANSITION_HOOK,
args
)
} }
return extend(baseProps, { return extend(baseProps, {
@ -141,7 +156,7 @@ export function resolveTransitionProps(
onEnter(el, done) { onEnter(el, done) {
nextFrame(() => { nextFrame(() => {
const resolve = () => finishEnter(el, done) const resolve = () => finishEnter(el, done)
onEnter && callHookWithErrorHandling(onEnter as Hook, [el, resolve]) callHook(onEnter, [el, resolve])
removeTransitionClass(el, enterFromClass) removeTransitionClass(el, enterFromClass)
addTransitionClass(el, enterToClass) addTransitionClass(el, enterToClass)
if (!(onEnter && onEnter.length > 1)) { if (!(onEnter && onEnter.length > 1)) {
@ -158,7 +173,7 @@ export function resolveTransitionProps(
addTransitionClass(el, leaveFromClass) addTransitionClass(el, leaveFromClass)
nextFrame(() => { nextFrame(() => {
const resolve = () => finishLeave(el, done) const resolve = () => finishLeave(el, done)
onLeave && callHookWithErrorHandling(onLeave as Hook, [el, resolve]) callHook(onLeave, [el, resolve])
removeTransitionClass(el, leaveFromClass) removeTransitionClass(el, leaveFromClass)
addTransitionClass(el, leaveToClass) addTransitionClass(el, leaveToClass)
if (!(onLeave && onLeave.length > 1)) { if (!(onLeave && onLeave.length > 1)) {
@ -170,8 +185,14 @@ export function resolveTransitionProps(
} }
}) })
}, },
onEnterCancelled: finishEnter, onEnterCancelled(el) {
onLeaveCancelled: finishLeave finishEnter(el)
onEnterCancelled && onEnterCancelled(el)
},
onLeaveCancelled(el) {
finishLeave(el)
onLeaveCancelled && onLeaveCancelled(el)
}
} as BaseTransitionProps<Element>) } as BaseTransitionProps<Element>)
} }

View File

@ -433,8 +433,7 @@ describe('e2e: Transition', () => {
'test-leave-active', 'test-leave-active',
'test-leave-from' 'test-leave-from'
]) ])
// fixme expect(enterCancelledSpy).toBeCalled()
expect(enterCancelledSpy).not.toBeCalled()
await nextFrame() await nextFrame()
expect(await classList('.test')).toStrictEqual([ expect(await classList('.test')).toStrictEqual([
'test', 'test',
@ -1255,8 +1254,8 @@ describe('e2e: Transition', () => {
createApp({ createApp({
template: ` template: `
<div id="container"> <div id="container">
<transition name="test"> <transition name="test" @leave-cancelled="onLeaveCancelledSpy">
<div v-show="toggle" class="test" @leave-cancelled="onLeaveCancelledSpy">content</div> <div v-show="toggle" class="test">content</div>
</transition> </transition>
</div> </div>
<button id="toggleBtn" @click="click">button</button> <button id="toggleBtn" @click="click">button</button>
@ -1290,8 +1289,7 @@ describe('e2e: Transition', () => {
'test-enter-active', 'test-enter-active',
'test-enter-from' 'test-enter-from'
]) ])
// fixme expect(onLeaveCancelledSpy).toBeCalled()
expect(onLeaveCancelledSpy).not.toBeCalled()
await nextFrame() await nextFrame()
expect(await classList('.test')).toStrictEqual([ expect(await classList('.test')).toStrictEqual([
'test', 'test',