Skip to content

Commit 299f529

Browse files
committed
fix transition enter hook for v-show (fix #3433)
1 parent 33bd509 commit 299f529

File tree

2 files changed

+88
-9
lines changed

2 files changed

+88
-9
lines changed

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

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,15 +92,17 @@ export function enter (vnode: VNodeWithData) {
9292
el._enterCb = null
9393
})
9494

95-
// remove pending leave element on enter by injecting an insert hook
96-
mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', () => {
97-
const parent = el.parentNode
98-
const pendingNode = parent._pending && parent._pending[vnode.key]
99-
if (pendingNode && pendingNode.tag === vnode.tag && pendingNode.elm._leaveCb) {
100-
pendingNode.elm._leaveCb()
101-
}
102-
enterHook && enterHook(el, cb)
103-
})
95+
if (!vnode.data.show) {
96+
// remove pending leave element on enter by injecting an insert hook
97+
mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', () => {
98+
const parent = el.parentNode
99+
const pendingNode = parent._pending && parent._pending[vnode.key]
100+
if (pendingNode && pendingNode.tag === vnode.tag && pendingNode.elm._leaveCb) {
101+
pendingNode.elm._leaveCb()
102+
}
103+
enterHook && enterHook(el, cb)
104+
})
105+
}
104106

105107
// start enter transition
106108
beforeEnterHook && beforeEnterHook(el)
@@ -115,6 +117,10 @@ export function enter (vnode: VNodeWithData) {
115117
})
116118
}
117119

120+
if (vnode.data.show) {
121+
enterHook && enterHook(el, cb)
122+
}
123+
118124
if (!expectsCSS && !userWantsControl) {
119125
cb()
120126
}

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

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,79 @@ if (!isIE9) {
253253
}).then(done)
254254
})
255255

256+
fit('transition events (v-show)', done => {
257+
const onLeaveSpy = jasmine.createSpy('leave')
258+
const onEnterSpy = jasmine.createSpy('enter')
259+
const beforeLeaveSpy = jasmine.createSpy('beforeLeave')
260+
const beforeEnterSpy = jasmine.createSpy('beforeEnter')
261+
const afterLeaveSpy = jasmine.createSpy('afterLeave')
262+
const afterEnterSpy = jasmine.createSpy('afterEnter')
263+
264+
const vm = new Vue({
265+
template: `
266+
<div>
267+
<transition
268+
name="test"
269+
@before-enter="beforeEnter"
270+
@enter="enter"
271+
@after-enter="afterEnter"
272+
@before-leave="beforeLeave"
273+
@leave="leave"
274+
@after-leave="afterLeave">
275+
<div v-show="ok" class="test">foo</div>
276+
</transition>
277+
</div>
278+
`,
279+
data: { ok: true },
280+
methods: {
281+
beforeLeave: (el) => {
282+
expect(el).toBe(vm.$el.children[0])
283+
expect(el.className).toBe('test')
284+
beforeLeaveSpy(el)
285+
},
286+
leave: (el) => onLeaveSpy(el),
287+
afterLeave: (el) => afterLeaveSpy(el),
288+
beforeEnter: (el) => {
289+
expect(el.className).toBe('test')
290+
beforeEnterSpy(el)
291+
},
292+
enter: (el) => {
293+
onEnterSpy(el)
294+
},
295+
afterEnter: (el) => afterEnterSpy(el)
296+
}
297+
}).$mount(el)
298+
299+
// should not apply transition on initial render by default
300+
expect(vm.$el.innerHTML).toBe('<div class="test">foo</div>')
301+
302+
let _el = vm.$el.children[0]
303+
vm.ok = false
304+
waitForUpdate(() => {
305+
expect(beforeLeaveSpy).toHaveBeenCalledWith(_el)
306+
expect(onLeaveSpy).toHaveBeenCalledWith(_el)
307+
expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active')
308+
}).thenWaitFor(nextFrame).then(() => {
309+
expect(afterLeaveSpy).not.toHaveBeenCalled()
310+
expect(vm.$el.children[0].className).toBe('test test-leave-active')
311+
}).thenWaitFor(duration + 10).then(() => {
312+
expect(afterLeaveSpy).toHaveBeenCalledWith(_el)
313+
expect(vm.$el.children[0].style.display).toBe('none')
314+
vm.ok = true
315+
}).then(() => {
316+
_el = vm.$el.children[0]
317+
expect(beforeEnterSpy).toHaveBeenCalledWith(_el)
318+
expect(onEnterSpy).toHaveBeenCalledWith(_el)
319+
expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
320+
}).thenWaitFor(nextFrame).then(() => {
321+
expect(afterEnterSpy).not.toHaveBeenCalled()
322+
expect(vm.$el.children[0].className).toBe('test test-enter-active')
323+
}).thenWaitFor(duration + 10).then(() => {
324+
expect(afterEnterSpy).toHaveBeenCalledWith(_el)
325+
expect(vm.$el.children[0].className).toBe('test')
326+
}).then(done)
327+
})
328+
256329
it('explicit user callback in JavaScript hooks', done => {
257330
let next
258331
const vm = new Vue({

0 commit comments

Comments
 (0)