mirror of
https://gitee.com/vuejs/vue.git
synced 2024-12-02 03:57:36 +08:00
test in-out early cancel with keep-alive
This commit is contained in:
parent
ccf3a61532
commit
210a3a22b0
@ -2,7 +2,7 @@
|
|||||||
// supports transition mode (out-in / in-out)
|
// supports transition mode (out-in / in-out)
|
||||||
|
|
||||||
import { warn } from 'core/util/index'
|
import { warn } from 'core/util/index'
|
||||||
import { noop, camelize } from 'shared/util'
|
import { camelize } from 'shared/util'
|
||||||
import { getRealChild, mergeVNodeHook } from 'core/vdom/helpers'
|
import { getRealChild, mergeVNodeHook } from 'core/vdom/helpers'
|
||||||
|
|
||||||
export const transitionProps = {
|
export const transitionProps = {
|
||||||
@ -110,16 +110,11 @@ export default {
|
|||||||
} else if (mode === 'in-out') {
|
} else if (mode === 'in-out') {
|
||||||
let delayedLeave
|
let delayedLeave
|
||||||
const performLeave = () => { delayedLeave() }
|
const performLeave = () => { delayedLeave() }
|
||||||
|
|
||||||
mergeVNodeHook(data, 'afterEnter', performLeave)
|
mergeVNodeHook(data, 'afterEnter', performLeave)
|
||||||
mergeVNodeHook(data, 'enterCancelled', performLeave)
|
mergeVNodeHook(data, 'enterCancelled', performLeave)
|
||||||
|
|
||||||
mergeVNodeHook(oldData, 'delayLeave', leave => {
|
mergeVNodeHook(oldData, 'delayLeave', leave => {
|
||||||
delayedLeave = leave
|
delayedLeave = leave
|
||||||
})
|
})
|
||||||
mergeVNodeHook(oldData, 'leaveCancelled', () => {
|
|
||||||
delayedLeave = noop
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,6 +160,10 @@ export function leave (vnode: VNodeWithData, rm: Function) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function performLeave () {
|
function performLeave () {
|
||||||
|
// the delayed leave may have already been cancelled
|
||||||
|
if (cb.cancelled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
// record leaving element
|
// record leaving element
|
||||||
if (!vnode.data.show) {
|
if (!vnode.data.show) {
|
||||||
(el.parentNode._pending || (el.parentNode._pending = {}))[vnode.key] = vnode
|
(el.parentNode._pending || (el.parentNode._pending = {}))[vnode.key] = vnode
|
||||||
|
@ -260,5 +260,71 @@ describe('Component keep-alive', () => {
|
|||||||
assertHookCalls(two, [1, 1, 1, 1, 0])
|
assertHookCalls(two, [1, 1, 1, 1, 0])
|
||||||
}).then(done)
|
}).then(done)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('dynamic components, in-out with early cancel', done => {
|
||||||
|
let next
|
||||||
|
const vm = new Vue({
|
||||||
|
template: `<div>
|
||||||
|
<transition name="test" mode="in-out" @after-enter="afterEnter">
|
||||||
|
<component :is="view" class="test" keep-alive></component>
|
||||||
|
</transition>
|
||||||
|
</div>`,
|
||||||
|
data: { view: 'one' },
|
||||||
|
components,
|
||||||
|
methods: {
|
||||||
|
afterEnter () {
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).$mount(el)
|
||||||
|
expect(vm.$el.textContent).toBe('one')
|
||||||
|
vm.view = 'two'
|
||||||
|
waitForUpdate(() => {
|
||||||
|
expect(vm.$el.innerHTML).toBe(
|
||||||
|
'<div class="test">one</div>' +
|
||||||
|
'<div class="test test-enter test-enter-active">two</div>'
|
||||||
|
)
|
||||||
|
}).thenWaitFor(nextFrame).then(() => {
|
||||||
|
expect(vm.$el.innerHTML).toBe(
|
||||||
|
'<div class="test">one</div>' +
|
||||||
|
'<div class="test test-enter-active">two</div>'
|
||||||
|
)
|
||||||
|
// switch again before enter finishes,
|
||||||
|
// this cancels both enter and leave.
|
||||||
|
vm.view = 'one'
|
||||||
|
}).then(() => {
|
||||||
|
// 1. the pending leaving "one" should be removed instantly.
|
||||||
|
// 2. the entering "two" should be placed into its final state instantly.
|
||||||
|
// 3. a new "one" is created and entering
|
||||||
|
expect(vm.$el.innerHTML).toBe(
|
||||||
|
'<div class="test">two</div>' +
|
||||||
|
'<div class="test test-enter test-enter-active">one</div>'
|
||||||
|
)
|
||||||
|
}).thenWaitFor(nextFrame).then(() => {
|
||||||
|
expect(vm.$el.innerHTML).toBe(
|
||||||
|
'<div class="test">two</div>' +
|
||||||
|
'<div class="test test-enter-active">one</div>'
|
||||||
|
)
|
||||||
|
}).thenWaitFor(_next => { next = _next }).then(() => {
|
||||||
|
expect(vm.$el.innerHTML).toBe(
|
||||||
|
'<div class="test">two</div>' +
|
||||||
|
'<div class="test">one</div>'
|
||||||
|
)
|
||||||
|
}).then(() => {
|
||||||
|
expect(vm.$el.innerHTML).toBe(
|
||||||
|
'<div class="test test-leave test-leave-active">two</div>' +
|
||||||
|
'<div class="test">one</div>'
|
||||||
|
)
|
||||||
|
}).thenWaitFor(nextFrame).then(() => {
|
||||||
|
expect(vm.$el.innerHTML).toBe(
|
||||||
|
'<div class="test test-leave-active">two</div>' +
|
||||||
|
'<div class="test">one</div>'
|
||||||
|
)
|
||||||
|
}).thenWaitFor(duration + 10).then(() => {
|
||||||
|
expect(vm.$el.innerHTML).toBe(
|
||||||
|
'<div class="test">one</div>'
|
||||||
|
)
|
||||||
|
}).then(done).then(done)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -142,7 +142,7 @@ if (!isIE9) {
|
|||||||
}).then(done)
|
}).then(done)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('dynamic components, in-out with leaveCancell', done => {
|
it('dynamic components, in-out with early cancel', done => {
|
||||||
let next
|
let next
|
||||||
const vm = new Vue({
|
const vm = new Vue({
|
||||||
template: `<div>
|
template: `<div>
|
||||||
|
Loading…
Reference in New Issue
Block a user