Skip to content

Commit 92ad0bd

Browse files
committed
ensure leave transitions and enter transitions are triggered in the same frame (fix #4510)
1 parent dacd0cf commit 92ad0bd

File tree

6 files changed

+109
-94
lines changed

6 files changed

+109
-94
lines changed

examples/move-animations/index.html

+7-5
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,19 @@
1515
border: 1px solid #666;
1616
box-sizing: border-box;
1717
}
18+
/* 1. define transition property, duration and easing */
1819
.fade-move, .fade-enter-active, .fade-leave-active {
1920
transition: all .5s cubic-bezier(.55,0,.1,1);
2021
}
21-
.fade-enter {
22+
/* 2. define enter from / leave to state */
23+
.fade-enter, .fade-leave-active {
2224
opacity: 0;
23-
transform: scaleY(0) translate(30px, 0);
25+
transform: scaleY(0.01) translate(30px, 0);
2426
}
25-
.fade-leave-active {
27+
/* 3. make leaving items position: absolute so that
28+
remaining items can animate to desired positions */
29+
.fade-leave, .fade-leave-active {
2630
position: absolute;
27-
opacity: 0;
28-
transform: scaleY(0.01) translate(30px, 0);
2931
}
3032
</style>
3133
<script src="https://cdn.jsdelivr.net/lodash/4.3.0/lodash.min.js"></script>

src/platforms/web/runtime/modules/transition.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ export function enter (vnode: VNodeWithData, toggleDisplay: ?() => void) {
112112
beforeEnterHook && beforeEnterHook(el)
113113
if (expectsCSS) {
114114
addTransitionClass(el, startClass)
115-
addTransitionClass(el, activeClass)
116115
nextFrame(() => {
117116
removeTransitionClass(el, startClass)
117+
addTransitionClass(el, activeClass)
118118
if (!cb.cancelled && !userWantsControl) {
119119
whenTransitionEnds(el, type, cb)
120120
}
@@ -206,9 +206,9 @@ export function leave (vnode: VNodeWithData, rm: Function) {
206206
beforeLeave && beforeLeave(el)
207207
if (expectsCSS) {
208208
addTransitionClass(el, leaveClass)
209-
addTransitionClass(el, leaveActiveClass)
210209
nextFrame(() => {
211210
removeTransitionClass(el, leaveClass)
211+
addTransitionClass(el, leaveActiveClass)
212212
if (!cb.cancelled && !userWantsControl) {
213213
whenTransitionEnds(el, type, cb)
214214
}

test/unit/features/component/component-keep-alive.spec.js

+15-15
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ describe('Component keep-alive', () => {
283283
vm.view = 'two'
284284
waitForUpdate(() => {
285285
expect(vm.$el.innerHTML).toBe(
286-
'<div class="test test-leave test-leave-active">one</div><!---->'
286+
'<div class="test test-leave">one</div><!---->'
287287
)
288288
assertHookCalls(one, [1, 1, 1, 1, 0])
289289
assertHookCalls(two, [0, 0, 0, 0, 0])
@@ -295,7 +295,7 @@ describe('Component keep-alive', () => {
295295
expect(vm.$el.innerHTML).toBe('<!---->')
296296
}).thenWaitFor(nextFrame).then(() => {
297297
expect(vm.$el.innerHTML).toBe(
298-
'<div class="test test-enter test-enter-active">two</div>'
298+
'<div class="test test-enter">two</div>'
299299
)
300300
assertHookCalls(one, [1, 1, 1, 1, 0])
301301
assertHookCalls(two, [1, 1, 1, 0, 0])
@@ -313,7 +313,7 @@ describe('Component keep-alive', () => {
313313
vm.view = 'one'
314314
}).then(() => {
315315
expect(vm.$el.innerHTML).toBe(
316-
'<div class="test test-leave test-leave-active">two</div><!---->'
316+
'<div class="test test-leave">two</div><!---->'
317317
)
318318
assertHookCalls(one, [1, 1, 1, 1, 0])
319319
assertHookCalls(two, [1, 1, 1, 1, 0])
@@ -325,7 +325,7 @@ describe('Component keep-alive', () => {
325325
expect(vm.$el.innerHTML).toBe('<!---->')
326326
}).thenWaitFor(nextFrame).then(() => {
327327
expect(vm.$el.innerHTML).toBe(
328-
'<div class="test test-enter test-enter-active">one</div>'
328+
'<div class="test test-enter">one</div>'
329329
)
330330
assertHookCalls(one, [1, 1, 2, 1, 0])
331331
assertHookCalls(two, [1, 1, 1, 1, 0])
@@ -369,7 +369,7 @@ describe('Component keep-alive', () => {
369369
waitForUpdate(() => {
370370
expect(vm.$el.innerHTML).toBe(
371371
'<div class="test">one</div>' +
372-
'<div class="test test-enter test-enter-active">two</div>'
372+
'<div class="test test-enter">two</div>'
373373
)
374374
assertHookCalls(one, [1, 1, 1, 1, 0])
375375
assertHookCalls(two, [1, 1, 1, 0, 0])
@@ -385,7 +385,7 @@ describe('Component keep-alive', () => {
385385
)
386386
}).then(() => {
387387
expect(vm.$el.innerHTML).toBe(
388-
'<div class="test test-leave test-leave-active">one</div>' +
388+
'<div class="test test-leave">one</div>' +
389389
'<div class="test">two</div>'
390390
)
391391
}).thenWaitFor(nextFrame).then(() => {
@@ -404,7 +404,7 @@ describe('Component keep-alive', () => {
404404
}).then(() => {
405405
expect(vm.$el.innerHTML).toBe(
406406
'<div class="test">two</div>' +
407-
'<div class="test test-enter test-enter-active">one</div>'
407+
'<div class="test test-enter">one</div>'
408408
)
409409
assertHookCalls(one, [1, 1, 2, 1, 0])
410410
assertHookCalls(two, [1, 1, 1, 1, 0])
@@ -420,7 +420,7 @@ describe('Component keep-alive', () => {
420420
)
421421
}).then(() => {
422422
expect(vm.$el.innerHTML).toBe(
423-
'<div class="test test-leave test-leave-active">two</div>' +
423+
'<div class="test test-leave">two</div>' +
424424
'<div class="test">one</div>'
425425
)
426426
}).thenWaitFor(nextFrame).then(() => {
@@ -460,7 +460,7 @@ describe('Component keep-alive', () => {
460460
waitForUpdate(() => {
461461
expect(vm.$el.innerHTML).toBe(
462462
'<div class="test">one</div>' +
463-
'<div class="test test-enter test-enter-active">two</div>'
463+
'<div class="test test-enter">two</div>'
464464
)
465465
}).thenWaitFor(nextFrame).then(() => {
466466
expect(vm.$el.innerHTML).toBe(
@@ -476,7 +476,7 @@ describe('Component keep-alive', () => {
476476
// 3. a new "one" is created and entering
477477
expect(vm.$el.innerHTML).toBe(
478478
'<div class="test">two</div>' +
479-
'<div class="test test-enter test-enter-active">one</div>'
479+
'<div class="test test-enter">one</div>'
480480
)
481481
}).thenWaitFor(nextFrame).then(() => {
482482
expect(vm.$el.innerHTML).toBe(
@@ -490,7 +490,7 @@ describe('Component keep-alive', () => {
490490
)
491491
}).then(() => {
492492
expect(vm.$el.innerHTML).toBe(
493-
'<div class="test test-leave test-leave-active">two</div>' +
493+
'<div class="test test-leave">two</div>' +
494494
'<div class="test">one</div>'
495495
)
496496
}).thenWaitFor(nextFrame).then(() => {
@@ -527,8 +527,8 @@ describe('Component keep-alive', () => {
527527
vm.view = 'bar'
528528
waitForUpdate(() => {
529529
expect(vm.$el.innerHTML).toBe(
530-
'<div class="test v-leave v-leave-active">foo</div>' +
531-
'<div class="test test-enter test-enter-active">bar</div>'
530+
'<div class="test v-leave">foo</div>' +
531+
'<div class="test test-enter">bar</div>'
532532
)
533533
}).thenWaitFor(nextFrame).then(() => {
534534
expect(vm.$el.innerHTML).toBe(
@@ -542,8 +542,8 @@ describe('Component keep-alive', () => {
542542
vm.view = 'foo'
543543
}).then(() => {
544544
expect(vm.$el.innerHTML).toBe(
545-
'<div class="test test-leave test-leave-active">bar</div>' +
546-
'<div class="test v-enter v-enter-active">foo</div>'
545+
'<div class="test test-leave">bar</div>' +
546+
'<div class="test v-enter">foo</div>'
547547
)
548548
}).thenWaitFor(nextFrame).then(() => {
549549
expect(vm.$el.innerHTML).toBe(

test/unit/features/transition/transition-group.spec.js

+22-13
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ if (!isIE9) {
4343
expect(vm.$el.innerHTML).toBe(
4444
`<span>` +
4545
['a', 'b', 'c'].map(i => `<div class="test">${i}</div>`).join('') +
46-
`<div class="test v-enter v-enter-active">d</div>` +
47-
`<div class="test v-enter v-enter-active">e</div>` +
46+
`<div class="test v-enter">d</div>` +
47+
`<div class="test v-enter">e</div>` +
4848
`</span>`
4949
)
5050
}).thenWaitFor(nextFrame).then(() => {
@@ -70,9 +70,9 @@ if (!isIE9) {
7070
waitForUpdate(() => {
7171
expect(vm.$el.innerHTML).toBe(
7272
`<span>` +
73-
`<div class="test v-leave v-leave-active">a</div>` +
73+
`<div class="test v-leave">a</div>` +
7474
`<div class="test">b</div>` +
75-
`<div class="test v-leave v-leave-active">c</div>` +
75+
`<div class="test v-leave">c</div>` +
7676
`</span>`
7777
)
7878
}).thenWaitFor(nextFrame).then(() => {
@@ -98,10 +98,10 @@ if (!isIE9) {
9898
waitForUpdate(() => {
9999
expect(vm.$el.innerHTML).toBe(
100100
`<span>` +
101-
`<div class="test v-leave v-leave-active">a</div>` +
101+
`<div class="test v-leave">a</div>` +
102102
`<div class="test">b</div>` +
103103
`<div class="test">c</div>` +
104-
`<div class="test v-enter v-enter-active">d</div>` +
104+
`<div class="test v-enter">d</div>` +
105105
`</span>`
106106
)
107107
}).thenWaitFor(nextFrame).then(() => {
@@ -128,10 +128,10 @@ if (!isIE9) {
128128
waitForUpdate(() => {
129129
expect(vm.$el.innerHTML).toBe(
130130
`<span>` +
131-
`<div class="test v-leave v-leave-active">a</div>` +
131+
`<div class="test v-leave">a</div>` +
132132
`<div class="test">b</div>` +
133133
`<div class="test">c</div>` +
134-
`<div class="test v-enter v-enter-active">d</div>` +
134+
`<div class="test v-enter">d</div>` +
135135
`</span>`
136136
)
137137
}).thenWaitFor(nextFrame).then(() => {
@@ -157,7 +157,7 @@ if (!isIE9) {
157157
waitForUpdate(() => {
158158
expect(vm.$el.innerHTML).toBe(
159159
`<span>` +
160-
vm.items.map(i => `<div class="test v-enter v-enter-active">${i}</div>`).join('') +
160+
vm.items.map(i => `<div class="test v-enter">${i}</div>`).join('') +
161161
`</span>`
162162
)
163163
}).thenWaitFor(nextFrame).then(() => {
@@ -216,10 +216,19 @@ if (!isIE9) {
216216
`<div class="test">a</div>` +
217217
`<div class="test">b</div>` +
218218
`<div class="test">c</div>` +
219-
`<div class="test v-enter v-enter-active">d</div>` +
219+
`<div class="test v-enter">d</div>` +
220220
`</span>`
221221
)
222222
expect(beforeEnterSpy.calls.count()).toBe(1)
223+
}).thenWaitFor(nextFrame).then(() => {
224+
expect(vm.$el.innerHTML).toBe(
225+
`<span>` +
226+
`<div class="test">a</div>` +
227+
`<div class="test">b</div>` +
228+
`<div class="test">c</div>` +
229+
`<div class="test v-enter-active">d</div>` +
230+
`</span>`
231+
)
223232
}).thenWaitFor(_next => { next = _next }).then(() => {
224233
expect(vm.$el.innerHTML).toBe(
225234
`<span>` +
@@ -261,10 +270,10 @@ if (!isIE9) {
261270
waitForUpdate(() => {
262271
expect(vm.$el.innerHTML.replace(/\s?style=""(\s?)/g, '$1')).toBe(
263272
`<span>` +
264-
`<div class="test group-enter group-enter-active">d</div>` +
273+
`<div class="test group-enter">d</div>` +
265274
`<div class="test">b</div>` +
266275
`<div class="test group-move">a</div>` +
267-
`<div class="test group-leave group-leave-active group-move">c</div>` +
276+
`<div class="test group-leave group-move">c</div>` +
268277
`</span>`
269278
)
270279
}).thenWaitFor(nextFrame).then(() => {
@@ -273,7 +282,7 @@ if (!isIE9) {
273282
`<div class="test group-enter-active">d</div>` +
274283
`<div class="test">b</div>` +
275284
`<div class="test group-move">a</div>` +
276-
`<div class="test group-leave-active group-move">c</div>` +
285+
`<div class="test group-move group-leave-active">c</div>` +
277286
`</span>`
278287
)
279288
}).thenWaitFor(duration * 2).then(() => {

0 commit comments

Comments
 (0)