Procházet zdrojové kódy

test in-out early cancel with keep-alive

Evan You před 10 roky
rodič
revize
210a3a22b0

+ 1 - 6
src/platforms/web/runtime/components/transition.js

@@ -2,7 +2,7 @@
 // supports transition mode (out-in / in-out)
 
 import { warn } from 'core/util/index'
-import { noop, camelize } from 'shared/util'
+import { camelize } from 'shared/util'
 import { getRealChild, mergeVNodeHook } from 'core/vdom/helpers'
 
 export const transitionProps = {
@@ -110,16 +110,11 @@ export default {
       } else if (mode === 'in-out') {
         let delayedLeave
         const performLeave = () => { delayedLeave() }
-
         mergeVNodeHook(data, 'afterEnter', performLeave)
         mergeVNodeHook(data, 'enterCancelled', performLeave)
-
         mergeVNodeHook(oldData, 'delayLeave', leave => {
           delayedLeave = leave
         })
-        mergeVNodeHook(oldData, 'leaveCancelled', () => {
-          delayedLeave = noop
-        })
       }
     }
 

+ 4 - 0
src/platforms/web/runtime/modules/transition.js

@@ -160,6 +160,10 @@ export function leave (vnode: VNodeWithData, rm: Function) {
   }
 
   function performLeave () {
+    // the delayed leave may have already been cancelled
+    if (cb.cancelled) {
+      return
+    }
     // record leaving element
     if (!vnode.data.show) {
       (el.parentNode._pending || (el.parentNode._pending = {}))[vnode.key] = vnode

+ 66 - 0
test/unit/features/component/component-keep-alive.spec.js

@@ -260,5 +260,71 @@ describe('Component keep-alive', () => {
         assertHookCalls(two, [1, 1, 1, 1, 0])
       }).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)
+    })
   }
 })

+ 1 - 1
test/unit/features/transition/transition-mode.spec.js

@@ -142,7 +142,7 @@ if (!isIE9) {
       }).then(done)
     })
 
-    it('dynamic components, in-out with leaveCancell', done => {
+    it('dynamic components, in-out with early cancel', done => {
       let next
       const vm = new Vue({
         template: `<div>