From 299f529498f096fa0c113f94ca58b60c330c98dc Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 12 Aug 2016 13:46:03 -0500 Subject: [PATCH] fix transition enter hook for v-show (fix #3433) --- .../web/runtime/modules/transition.js | 24 +++--- .../features/transition/transition.spec.js | 73 +++++++++++++++++++ 2 files changed, 88 insertions(+), 9 deletions(-) diff --git a/src/platforms/web/runtime/modules/transition.js b/src/platforms/web/runtime/modules/transition.js index af2d7d76..af038114 100644 --- a/src/platforms/web/runtime/modules/transition.js +++ b/src/platforms/web/runtime/modules/transition.js @@ -92,15 +92,17 @@ export function enter (vnode: VNodeWithData) { el._enterCb = null }) - // remove pending leave element on enter by injecting an insert hook - mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', () => { - const parent = el.parentNode - const pendingNode = parent._pending && parent._pending[vnode.key] - if (pendingNode && pendingNode.tag === vnode.tag && pendingNode.elm._leaveCb) { - pendingNode.elm._leaveCb() - } - enterHook && enterHook(el, cb) - }) + if (!vnode.data.show) { + // remove pending leave element on enter by injecting an insert hook + mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', () => { + const parent = el.parentNode + const pendingNode = parent._pending && parent._pending[vnode.key] + if (pendingNode && pendingNode.tag === vnode.tag && pendingNode.elm._leaveCb) { + pendingNode.elm._leaveCb() + } + enterHook && enterHook(el, cb) + }) + } // start enter transition beforeEnterHook && beforeEnterHook(el) @@ -115,6 +117,10 @@ export function enter (vnode: VNodeWithData) { }) } + if (vnode.data.show) { + enterHook && enterHook(el, cb) + } + if (!expectsCSS && !userWantsControl) { cb() } diff --git a/test/unit/features/transition/transition.spec.js b/test/unit/features/transition/transition.spec.js index 459d8326..74712f50 100644 --- a/test/unit/features/transition/transition.spec.js +++ b/test/unit/features/transition/transition.spec.js @@ -253,6 +253,79 @@ if (!isIE9) { }).then(done) }) + fit('transition events (v-show)', done => { + const onLeaveSpy = jasmine.createSpy('leave') + const onEnterSpy = jasmine.createSpy('enter') + const beforeLeaveSpy = jasmine.createSpy('beforeLeave') + const beforeEnterSpy = jasmine.createSpy('beforeEnter') + const afterLeaveSpy = jasmine.createSpy('afterLeave') + const afterEnterSpy = jasmine.createSpy('afterEnter') + + const vm = new Vue({ + template: ` +
+ +
foo
+
+
+ `, + data: { ok: true }, + methods: { + beforeLeave: (el) => { + expect(el).toBe(vm.$el.children[0]) + expect(el.className).toBe('test') + beforeLeaveSpy(el) + }, + leave: (el) => onLeaveSpy(el), + afterLeave: (el) => afterLeaveSpy(el), + beforeEnter: (el) => { + expect(el.className).toBe('test') + beforeEnterSpy(el) + }, + enter: (el) => { + onEnterSpy(el) + }, + afterEnter: (el) => afterEnterSpy(el) + } + }).$mount(el) + + // should not apply transition on initial render by default + expect(vm.$el.innerHTML).toBe('
foo
') + + let _el = vm.$el.children[0] + vm.ok = false + waitForUpdate(() => { + expect(beforeLeaveSpy).toHaveBeenCalledWith(_el) + expect(onLeaveSpy).toHaveBeenCalledWith(_el) + expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active') + }).thenWaitFor(nextFrame).then(() => { + expect(afterLeaveSpy).not.toHaveBeenCalled() + expect(vm.$el.children[0].className).toBe('test test-leave-active') + }).thenWaitFor(duration + 10).then(() => { + expect(afterLeaveSpy).toHaveBeenCalledWith(_el) + expect(vm.$el.children[0].style.display).toBe('none') + vm.ok = true + }).then(() => { + _el = vm.$el.children[0] + expect(beforeEnterSpy).toHaveBeenCalledWith(_el) + expect(onEnterSpy).toHaveBeenCalledWith(_el) + expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active') + }).thenWaitFor(nextFrame).then(() => { + expect(afterEnterSpy).not.toHaveBeenCalled() + expect(vm.$el.children[0].className).toBe('test test-enter-active') + }).thenWaitFor(duration + 10).then(() => { + expect(afterEnterSpy).toHaveBeenCalledWith(_el) + expect(vm.$el.children[0].className).toBe('test') + }).then(done) + }) + it('explicit user callback in JavaScript hooks', done => { let next const vm = new Vue({