From e2618a632d4add2819ffb8b575af0da189dc3204 Mon Sep 17 00:00:00 2001 From: luwuer Date: Thu, 3 Dec 2020 03:41:20 +0800 Subject: [PATCH] fix(transition): respect rules in *-leave-from transition class (#2597) fix #2593 --- .../runtime-dom/src/components/Transition.ts | 24 ++++++++++++------- packages/vue/__tests__/Transition.spec.ts | 3 ++- .../vue/__tests__/TransitionGroup.spec.ts | 19 ++++++++------- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/packages/runtime-dom/src/components/Transition.ts b/packages/runtime-dom/src/components/Transition.ts index b969b69736b..49ed2d4d5f9 100644 --- a/packages/runtime-dom/src/components/Transition.ts +++ b/packages/runtime-dom/src/components/Transition.ts @@ -27,6 +27,14 @@ export interface TransitionProps extends BaseTransitionProps { leaveToClass?: string } +export interface ElementWithTransition extends HTMLElement { + // _vtc = Vue Transition Classes. + // Store the temporarily-added transition classes on the element + // so that we can avoid overwriting them if the element's class is patched + // during the transition. + _vtc?: Set +} + // DOM Transition is a higher-order-component based on the platform-agnostic // base Transition component, with DOM-specific logic. export const Transition: FunctionalComponent = ( @@ -149,7 +157,15 @@ export function resolveTransitionProps( const resolve = () => finishLeave(el, done) addTransitionClass(el, leaveActiveClass) addTransitionClass(el, leaveFromClass) + // ref #2531, #2593 + // disabling the transition before nextFrame ensures styles from + // *-leave-from and *-enter-from classes are applied instantly before + // the transition starts. This is applied for enter transition as well + // so that it accounts for `visibility: hidden` cases. + const cachedTransition = (el as HTMLElement).style.transitionProperty + ;(el as HTMLElement).style.transitionProperty = 'none' nextFrame(() => { + ;(el as HTMLElement).style.transitionProperty = cachedTransition removeTransitionClass(el, leaveFromClass) addTransitionClass(el, leaveToClass) if (!(onLeave && onLeave.length > 1)) { @@ -206,14 +222,6 @@ function validateDuration(val: unknown) { } } -export interface ElementWithTransition extends HTMLElement { - // _vtc = Vue Transition Classes. - // Store the temporarily-added transition classes on the element - // so that we can avoid overwriting them if the element's class is patched - // during the transition. - _vtc?: Set -} - export function addTransitionClass(el: Element, cls: string) { cls.split(/\s+/).forEach(c => c && el.classList.add(c)) ;( diff --git a/packages/vue/__tests__/Transition.spec.ts b/packages/vue/__tests__/Transition.spec.ts index 93959e45d50..ee9b8cf6515 100644 --- a/packages/vue/__tests__/Transition.spec.ts +++ b/packages/vue/__tests__/Transition.spec.ts @@ -1305,9 +1305,10 @@ describe('e2e: Transition', () => { await classWhenTransitionStart() await nextFrame() expect(await html('#container')).toBe( - '
one
' + '
one
' ) await transitionFinish() + await nextFrame() expect(await html('#container')).toBe( '
two
' ) diff --git a/packages/vue/__tests__/TransitionGroup.spec.ts b/packages/vue/__tests__/TransitionGroup.spec.ts index dee092ff677..c3d2aa28ec4 100644 --- a/packages/vue/__tests__/TransitionGroup.spec.ts +++ b/packages/vue/__tests__/TransitionGroup.spec.ts @@ -8,6 +8,7 @@ describe('e2e: TransitionGroup', () => { const duration = 50 const buffer = 5 + const transitionDisableProp = `style="transition-property: none;"` const htmlWhenTransitionStart = () => page().evaluate(() => { @@ -106,15 +107,15 @@ describe('e2e: TransitionGroup', () => { ) expect(await htmlWhenTransitionStart()).toBe( - `
a
` + + `
a
` + `
b
` + - `
c
` + `
c
` ) await nextFrame() expect(await html('#container')).toBe( - `
a
` + + `
a
` + `
b
` + - `
c
` + `
c
` ) await transitionFinish() expect(await html('#container')).toBe(`
b
`) @@ -150,14 +151,14 @@ describe('e2e: TransitionGroup', () => { ) expect(await htmlWhenTransitionStart()).toBe( - `
a
` + + `
a
` + `
b
` + `
c
` + `
d
` ) await nextFrame() expect(await html('#container')).toBe( - `
a
` + + `
a
` + `
b
` + `
c
` + `
d
` @@ -278,7 +279,7 @@ describe('e2e: TransitionGroup', () => { `
d
` + `
b
` + `
a
` + - `
c
` + `
c
` ) await nextFrame() expect(await html('#container')).toBe( @@ -461,7 +462,7 @@ describe('e2e: TransitionGroup', () => { // enter + leave expect(await htmlWhenTransitionStart()).toBe( - `
a
` + + `
a
` + `
b
` + `
c
` + `
d
` @@ -474,7 +475,7 @@ describe('e2e: TransitionGroup', () => { expect(afterEnterSpy).not.toBeCalled() await nextFrame() expect(await html('#container')).toBe( - `
a
` + + `
a
` + `
b
` + `
c
` + `
d
`