Skip to content

Commit ba4203f

Browse files
committed
test(transition): test case for reflow after adding *-leave-from and before *-leave-active
1 parent 29ee234 commit ba4203f

File tree

4 files changed

+77
-2
lines changed

4 files changed

+77
-2
lines changed

Diff for: packages/runtime-dom/src/components/Transition.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -259,11 +259,11 @@ export function resolveTransitionProps(
259259
// add *-leave-active class before reflow so in the case of a cancelled enter transition
260260
// the css will not get the final state (#10677)
261261
if (!el._enterCancelled) {
262+
// force reflow so *-leave-from classes immediately take effect (#2593)
262263
forceReflow()
263264
addTransitionClass(el, leaveActiveClass)
264265
} else {
265266
addTransitionClass(el, leaveActiveClass)
266-
// force reflow so *-leave-from classes immediately take effect (#2593)
267267
forceReflow()
268268
}
269269
nextFrame(() => {

Diff for: packages/vue/__tests__/e2e/Transition.spec.ts

+51-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import path from 'node:path'
33
import { Transition, createApp, h, nextTick, ref } from 'vue'
44

55
describe('e2e: Transition', () => {
6-
const { page, html, classList, isVisible, timeout, nextFrame, click } =
6+
const { page, html, classList, style, isVisible, timeout, nextFrame, click } =
77
setupPuppeteer()
88
const baseUrl = `file://${path.resolve(__dirname, './transition.html')}`
99

@@ -2986,6 +2986,56 @@ describe('e2e: Transition', () => {
29862986
)
29872987
})
29882988

2989+
test('reflow after *-leave-from before *-leave-active', async () => {
2990+
await page().evaluate(() => {
2991+
const { createApp, ref } = (window as any).Vue
2992+
createApp({
2993+
template: `
2994+
<div id="container">
2995+
<transition name="test-reflow">
2996+
<div v-if="toggle" class="test-reflow">content</div>
2997+
</transition>
2998+
</div>
2999+
<button id="toggleBtn" @click="click">button</button>
3000+
`,
3001+
setup: () => {
3002+
const toggle = ref(false)
3003+
const click = () => (toggle.value = !toggle.value)
3004+
return {
3005+
toggle,
3006+
click,
3007+
}
3008+
},
3009+
}).mount('#app')
3010+
})
3011+
3012+
// if transition starts while there's v-leave-active added along with v-leave-from, its bad, it has to start when it doesnt have the v-leave-from
3013+
3014+
// enter
3015+
await classWhenTransitionStart()
3016+
await transitionFinish()
3017+
3018+
// leave
3019+
expect(await classWhenTransitionStart()).toStrictEqual([
3020+
'test-reflow',
3021+
'test-reflow-leave-from',
3022+
'test-reflow-leave-active',
3023+
])
3024+
3025+
console.log(await style('.test-reflow', 'opacity'))
3026+
expect(await style('.test-reflow', 'opacity')).toStrictEqual('0.9')
3027+
3028+
await nextFrame()
3029+
expect(await classList('.test-reflow')).toStrictEqual([
3030+
'test-reflow',
3031+
'test-reflow-leave-active',
3032+
'test-reflow-leave-to',
3033+
])
3034+
3035+
await transitionFinish()
3036+
expect(await html('#container')).toBe('<!--v-if-->')
3037+
})
3038+
29893039
test('warn when used on multiple elements', async () => {
29903040
createApp({
29913041
render() {

Diff for: packages/vue/__tests__/e2e/e2eUtils.ts

+15
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ interface PuppeteerUtils {
3939
value(selector: string): Promise<string>
4040
html(selector: string): Promise<string>
4141
classList(selector: string): Promise<string[]>
42+
style(selector: string, property: keyof CSSStyleDeclaration): Promise<any>
4243
children(selector: string): Promise<any[]>
4344
isVisible(selector: string): Promise<boolean>
4445
isChecked(selector: string): Promise<boolean>
@@ -120,6 +121,19 @@ export function setupPuppeteer(args?: string[]): PuppeteerUtils {
120121
return page.$eval(selector, (node: any) => [...node.children])
121122
}
122123

124+
async function style(
125+
selector: string,
126+
property: keyof CSSStyleDeclaration,
127+
): Promise<any> {
128+
return await page.$eval(
129+
selector,
130+
(node, property) => {
131+
return window.getComputedStyle(node)[property]
132+
},
133+
property,
134+
)
135+
}
136+
123137
async function isVisible(selector: string): Promise<boolean> {
124138
const display = await page.$eval(selector, node => {
125139
return window.getComputedStyle(node).display
@@ -195,6 +209,7 @@ export function setupPuppeteer(args?: string[]): PuppeteerUtils {
195209
value,
196210
html,
197211
classList,
212+
style,
198213
children,
199214
isVisible,
200215
isChecked,

Diff for: packages/vue/__tests__/e2e/transition.html

+10
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,21 @@
1616
.test-appear,
1717
.test-enter,
1818
.test-leave-active,
19+
.test-reflow-enter,
20+
.test-reflow-leave-to,
1921
.hello,
2022
.bye.active,
2123
.changed-enter {
2224
opacity: 0;
2325
}
26+
.test-reflow-leave-active,
27+
.test-reflow-enter-active {
28+
-webkit-transition: opacity 50ms ease;
29+
transition: opacity 50ms ease;
30+
}
31+
.test-reflow-leave-from {
32+
opacity: 0.9;
33+
}
2434
.test-anim-enter-active {
2535
animation: test-enter 50ms;
2636
-webkit-animation: test-enter 50ms;

0 commit comments

Comments
 (0)