fix(transition): handle errors in CSSTransition onEnter & onLeave
This commit is contained in:
parent
a6aa64b0cc
commit
55b7bf991d
@ -4,9 +4,11 @@ import {
|
|||||||
h,
|
h,
|
||||||
warn,
|
warn,
|
||||||
FunctionalComponent,
|
FunctionalComponent,
|
||||||
getCurrentInstance
|
getCurrentInstance,
|
||||||
|
callWithAsyncErrorHandling
|
||||||
} from '@vue/runtime-core'
|
} from '@vue/runtime-core'
|
||||||
import { isObject } from '@vue/shared'
|
import { isObject } from '@vue/shared'
|
||||||
|
import { ErrorCodes } from 'packages/runtime-core/src/errorHandling'
|
||||||
|
|
||||||
const TRANSITION = 'transition'
|
const TRANSITION = 'transition'
|
||||||
const ANIMATION = 'animation'
|
const ANIMATION = 'animation'
|
||||||
@ -27,6 +29,8 @@ export interface CSSTransitionProps extends TransitionProps {
|
|||||||
leaveToClass?: string
|
leaveToClass?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CSSTransition is a higher-order-component based on the platform-agnostic
|
||||||
|
// base Transition component, with DOM-specific logic.
|
||||||
export const CSSTransition: FunctionalComponent = (
|
export const CSSTransition: FunctionalComponent = (
|
||||||
props: CSSTransitionProps,
|
props: CSSTransitionProps,
|
||||||
{ slots }
|
{ slots }
|
||||||
@ -65,6 +69,7 @@ function resolveCSSTransitionProps({
|
|||||||
leaveToClass = `${name}-leave-to`,
|
leaveToClass = `${name}-leave-to`,
|
||||||
...baseProps
|
...baseProps
|
||||||
}: CSSTransitionProps): TransitionProps {
|
}: CSSTransitionProps): TransitionProps {
|
||||||
|
const instance = getCurrentInstance()!
|
||||||
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]
|
||||||
@ -77,18 +82,26 @@ function resolveCSSTransitionProps({
|
|||||||
enterToClass = appearToClass
|
enterToClass = appearToClass
|
||||||
}
|
}
|
||||||
|
|
||||||
function finishEnter(el: Element, done?: () => void) {
|
type Hook = (el: Element, done?: () => void) => void
|
||||||
|
|
||||||
|
const finishEnter: Hook = (el, done) => {
|
||||||
removeTransitionClass(el, enterToClass)
|
removeTransitionClass(el, enterToClass)
|
||||||
removeTransitionClass(el, enterActiveClass)
|
removeTransitionClass(el, enterActiveClass)
|
||||||
done && done()
|
done && done()
|
||||||
}
|
}
|
||||||
|
|
||||||
function finishLeave(el: Element, done?: () => void) {
|
const finishLeave: Hook = (el, done) => {
|
||||||
removeTransitionClass(el, leaveToClass)
|
removeTransitionClass(el, leaveToClass)
|
||||||
removeTransitionClass(el, leaveActiveClass)
|
removeTransitionClass(el, leaveActiveClass)
|
||||||
done && done()
|
done && done()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// only needed for user hooks called in nextFrame
|
||||||
|
// sync errors are already handled by BaseTransition
|
||||||
|
function callHookWithErrorHandling(hook: Hook, args: any[]) {
|
||||||
|
callWithAsyncErrorHandling(hook, instance, ErrorCodes.TRANSITION_HOOK, args)
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...baseProps,
|
...baseProps,
|
||||||
onBeforeEnter(el) {
|
onBeforeEnter(el) {
|
||||||
@ -99,7 +112,7 @@ function resolveCSSTransitionProps({
|
|||||||
onEnter(el, done) {
|
onEnter(el, done) {
|
||||||
nextFrame(() => {
|
nextFrame(() => {
|
||||||
const resolve = () => finishEnter(el, done)
|
const resolve = () => finishEnter(el, done)
|
||||||
onEnter && onEnter(el, resolve)
|
onEnter && callHookWithErrorHandling(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)) {
|
||||||
@ -116,7 +129,7 @@ function resolveCSSTransitionProps({
|
|||||||
addTransitionClass(el, leaveFromClass)
|
addTransitionClass(el, leaveFromClass)
|
||||||
nextFrame(() => {
|
nextFrame(() => {
|
||||||
const resolve = () => finishLeave(el, done)
|
const resolve = () => finishLeave(el, done)
|
||||||
onLeave && onLeave(el, resolve)
|
onLeave && callHookWithErrorHandling(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)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user