diff --git a/src/platforms/web/runtime/modules/transition.js b/src/platforms/web/runtime/modules/transition.js index 0d099c9947f..0796b5dad5e 100644 --- a/src/platforms/web/runtime/modules/transition.js +++ b/src/platforms/web/runtime/modules/transition.js @@ -149,13 +149,15 @@ export function enter (vnode: VNodeWithData, toggleDisplay: ?() => void) { addTransitionClass(el, startClass) addTransitionClass(el, activeClass) nextFrame(() => { - addTransitionClass(el, toClass) removeTransitionClass(el, startClass) - if (!cb.cancelled && !userWantsControl) { - if (isValidDuration(explicitEnterDuration)) { - setTimeout(cb, explicitEnterDuration) - } else { - whenTransitionEnds(el, type, cb) + if (!cb.cancelled) { + addTransitionClass(el, toClass) + if (!userWantsControl) { + if (isValidDuration(explicitEnterDuration)) { + setTimeout(cb, explicitEnterDuration) + } else { + whenTransitionEnds(el, type, cb) + } } } }) @@ -257,13 +259,15 @@ export function leave (vnode: VNodeWithData, rm: Function) { addTransitionClass(el, leaveClass) addTransitionClass(el, leaveActiveClass) nextFrame(() => { - addTransitionClass(el, leaveToClass) removeTransitionClass(el, leaveClass) - if (!cb.cancelled && !userWantsControl) { - if (isValidDuration(explicitLeaveDuration)) { - setTimeout(cb, explicitLeaveDuration) - } else { - whenTransitionEnds(el, type, cb) + if (!cb.cancelled) { + addTransitionClass(el, leaveToClass) + if (!userWantsControl) { + if (isValidDuration(explicitLeaveDuration)) { + setTimeout(cb, explicitLeaveDuration) + } else { + whenTransitionEnds(el, type, cb) + } } } }) diff --git a/test/unit/features/transition/transition.spec.js b/test/unit/features/transition/transition.spec.js index 5e4dcc7eac3..f7b08e376a5 100644 --- a/test/unit/features/transition/transition.spec.js +++ b/test/unit/features/transition/transition.spec.js @@ -612,6 +612,50 @@ if (!isIE9) { }).then(done) }) + it('leave transition with v-show: cancelled on next frame', done => { + const vm = new Vue({ + template: ` +
+ +
foo
+
+
+ `, + data: { ok: true } + }).$mount(el) + + vm.ok = false + waitForUpdate(() => { + vm.ok = true + }).thenWaitFor(nextFrame).then(() => { + expect(vm.$el.children[0].className).toBe('test test-enter-active test-enter-to') + }).thenWaitFor(duration + buffer).then(() => { + expect(vm.$el.children[0].className).toBe('test') + }).then(done) + }) + + it('enter transition with v-show: cancelled on next frame', done => { + const vm = new Vue({ + template: ` +
+ +
foo
+
+
+ `, + data: { ok: false } + }).$mount(el) + + vm.ok = true + waitForUpdate(() => { + vm.ok = false + }).thenWaitFor(nextFrame).then(() => { + expect(vm.$el.children[0].className).toBe('test test-leave-active test-leave-to') + }).thenWaitFor(duration + buffer).then(() => { + expect(vm.$el.children[0].className).toBe('test') + }).then(done) + }) + it('animations', done => { const vm = new Vue({ template: `