]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(transition): respect rules in *-leave-from transition class (#2597)
authorluwuer <html6@foxmail.com>
Wed, 2 Dec 2020 19:41:20 +0000 (03:41 +0800)
committerGitHub <noreply@github.com>
Wed, 2 Dec 2020 19:41:20 +0000 (14:41 -0500)
fix #2593

packages/runtime-dom/src/components/Transition.ts
packages/vue/__tests__/Transition.spec.ts
packages/vue/__tests__/TransitionGroup.spec.ts

index b969b69736bbb797f11e6eba463c9c4eb44e6eb9..49ed2d4d5f98ae9c7d19cc14845406bdfa281c59 100644 (file)
@@ -27,6 +27,14 @@ export interface TransitionProps extends BaseTransitionProps<Element> {
   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<string>
+}
+
 // DOM Transition is a higher-order-component based on the platform-agnostic
 // base Transition component, with DOM-specific logic.
 export const Transition: FunctionalComponent<TransitionProps> = (
@@ -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<string>
-}
-
 export function addTransitionClass(el: Element, cls: string) {
   cls.split(/\s+/).forEach(c => c && el.classList.add(c))
   ;(
index 93959e45d5008332f1d69b5ad1fa42bc99d007cf..ee9b8cf65153c31acfa9055f249734778bfc567e 100644 (file)
@@ -1305,9 +1305,10 @@ describe('e2e: Transition', () => {
         await classWhenTransitionStart()
         await nextFrame()
         expect(await html('#container')).toBe(
-          '<div class="test v-leave-active v-leave-to">one</div>'
+          '<div class="test v-leave-active v-leave-to" style="">one</div>'
         )
         await transitionFinish()
+        await nextFrame()
         expect(await html('#container')).toBe(
           '<div class="test v-enter-active v-enter-to">two</div>'
         )
index dee092ff67769a059ab5d2507e13a44213c6db0a..c3d2aa28ec44c69d340ab6ab5448212910536550 100644 (file)
@@ -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(
-        `<div class="test test-leave-active test-leave-from">a</div>` +
+        `<div class="test test-leave-active test-leave-from" ${transitionDisableProp}>a</div>` +
           `<div class="test">b</div>` +
-          `<div class="test test-leave-active test-leave-from">c</div>`
+          `<div class="test test-leave-active test-leave-from" ${transitionDisableProp}>c</div>`
       )
       await nextFrame()
       expect(await html('#container')).toBe(
-        `<div class="test test-leave-active test-leave-to">a</div>` +
+        `<div class="test test-leave-active test-leave-to" style="">a</div>` +
           `<div class="test">b</div>` +
-          `<div class="test test-leave-active test-leave-to">c</div>`
+          `<div class="test test-leave-active test-leave-to" style="">c</div>`
       )
       await transitionFinish()
       expect(await html('#container')).toBe(`<div class="test">b</div>`)
@@ -150,14 +151,14 @@ describe('e2e: TransitionGroup', () => {
       )
 
       expect(await htmlWhenTransitionStart()).toBe(
-        `<div class="test test-leave-active test-leave-from">a</div>` +
+        `<div class="test test-leave-active test-leave-from" ${transitionDisableProp}>a</div>` +
           `<div class="test">b</div>` +
           `<div class="test">c</div>` +
           `<div class="test test-enter-active test-enter-from">d</div>`
       )
       await nextFrame()
       expect(await html('#container')).toBe(
-        `<div class="test test-leave-active test-leave-to">a</div>` +
+        `<div class="test test-leave-active test-leave-to" style="">a</div>` +
           `<div class="test">b</div>` +
           `<div class="test">c</div>` +
           `<div class="test test-enter-active test-enter-to">d</div>`
@@ -278,7 +279,7 @@ describe('e2e: TransitionGroup', () => {
         `<div class="test group-enter-active group-enter-from">d</div>` +
           `<div class="test">b</div>` +
           `<div class="test group-move" style="">a</div>` +
-          `<div class="test group-leave-active group-leave-from group-move" style="">c</div>`
+          `<div class="test group-leave-active group-leave-from group-move" ${transitionDisableProp}>c</div>`
       )
       await nextFrame()
       expect(await html('#container')).toBe(
@@ -461,7 +462,7 @@ describe('e2e: TransitionGroup', () => {
 
       // enter + leave
       expect(await htmlWhenTransitionStart()).toBe(
-        `<div class="test test-leave-active test-leave-from">a</div>` +
+        `<div class="test test-leave-active test-leave-from" ${transitionDisableProp}>a</div>` +
           `<div class="test">b</div>` +
           `<div class="test">c</div>` +
           `<div class="test test-enter-active test-enter-from">d</div>`
@@ -474,7 +475,7 @@ describe('e2e: TransitionGroup', () => {
       expect(afterEnterSpy).not.toBeCalled()
       await nextFrame()
       expect(await html('#container')).toBe(
-        `<div class="test test-leave-active test-leave-to">a</div>` +
+        `<div class="test test-leave-active test-leave-to" style="">a</div>` +
           `<div class="test">b</div>` +
           `<div class="test">c</div>` +
           `<div class="test test-enter-active test-enter-to">d</div>`