Просмотр исходного кода

add new transition to-state classes

Evan You 9 лет назад
Родитель
Сommit
0cbc96101d

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

@@ -15,10 +15,13 @@ export const transitionProps = {
   type: String,
   enterClass: String,
   leaveClass: String,
+  enterToClass: String,
+  leaveToClass: String,
   enterActiveClass: String,
   leaveActiveClass: String,
   appearClass: String,
-  appearActiveClass: String
+  appearActiveClass: String,
+  appearToClass: String
 }
 
 // in case the child is also an abstract component, e.g. <keep-alive>

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

@@ -34,8 +34,10 @@ export function enter (vnode: VNodeWithData, toggleDisplay: ?() => void) {
     css,
     type,
     enterClass,
+    enterToClass,
     enterActiveClass,
     appearClass,
+    appearToClass,
     appearActiveClass,
     beforeEnter,
     enter,
@@ -66,6 +68,7 @@ export function enter (vnode: VNodeWithData, toggleDisplay: ?() => void) {
 
   const startClass = isAppear ? appearClass : enterClass
   const activeClass = isAppear ? appearActiveClass : enterActiveClass
+  const toClass = isAppear ? appearToClass : enterToClass
   const beforeEnterHook = isAppear ? (beforeAppear || beforeEnter) : beforeEnter
   const enterHook = isAppear ? (typeof appear === 'function' ? appear : enter) : enter
   const afterEnterHook = isAppear ? (afterAppear || afterEnter) : afterEnter
@@ -80,6 +83,7 @@ export function enter (vnode: VNodeWithData, toggleDisplay: ?() => void) {
 
   const cb = el._enterCb = once(() => {
     if (expectsCSS) {
+      removeTransitionClass(el, toClass)
       removeTransitionClass(el, activeClass)
     }
     if (cb.cancelled) {
@@ -114,6 +118,7 @@ export function enter (vnode: VNodeWithData, toggleDisplay: ?() => void) {
     addTransitionClass(el, startClass)
     addTransitionClass(el, activeClass)
     nextFrame(() => {
+      addTransitionClass(el, toClass)
       removeTransitionClass(el, startClass)
       if (!cb.cancelled && !userWantsControl) {
         whenTransitionEnds(el, type, cb)
@@ -154,6 +159,7 @@ export function leave (vnode: VNodeWithData, rm: Function) {
     css,
     type,
     leaveClass,
+    leaveToClass,
     leaveActiveClass,
     beforeLeave,
     leave,
@@ -174,6 +180,7 @@ export function leave (vnode: VNodeWithData, rm: Function) {
       el.parentNode._pending[vnode.key] = null
     }
     if (expectsCSS) {
+      removeTransitionClass(el, leaveToClass)
       removeTransitionClass(el, leaveActiveClass)
     }
     if (cb.cancelled) {
@@ -208,6 +215,7 @@ export function leave (vnode: VNodeWithData, rm: Function) {
       addTransitionClass(el, leaveClass)
       addTransitionClass(el, leaveActiveClass)
       nextFrame(() => {
+        addTransitionClass(el, leaveToClass)
         removeTransitionClass(el, leaveClass)
         if (!cb.cancelled && !userWantsControl) {
           whenTransitionEnds(el, type, cb)
@@ -243,6 +251,9 @@ const autoCssTransition: (name: string) => Object = cached(name => {
     enterClass: `${name}-enter`,
     leaveClass: `${name}-leave`,
     appearClass: `${name}-enter`,
+    enterToClass: `${name}-enter-to`,
+    leaveToClass: `${name}-leave-to`,
+    appearToClass: `${name}-enter-to`,
     enterActiveClass: `${name}-enter-active`,
     leaveActiveClass: `${name}-leave-active`,
     appearActiveClass: `${name}-enter-active`

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

@@ -289,7 +289,7 @@ describe('Component keep-alive', () => {
         assertHookCalls(two, [0, 0, 0, 0, 0])
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test test-leave-active">one</div><!---->'
+          '<div class="test test-leave-active test-leave-to">one</div><!---->'
         )
       }).thenWaitFor(_next => { next = _next }).then(() => {
         expect(vm.$el.innerHTML).toBe('<!---->')
@@ -301,7 +301,7 @@ describe('Component keep-alive', () => {
         assertHookCalls(two, [1, 1, 1, 0, 0])
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test test-enter-active">two</div>'
+          '<div class="test test-enter-active test-enter-to">two</div>'
         )
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.innerHTML).toBe(
@@ -319,7 +319,7 @@ describe('Component keep-alive', () => {
         assertHookCalls(two, [1, 1, 1, 1, 0])
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test test-leave-active">two</div><!---->'
+          '<div class="test test-leave-active test-leave-to">two</div><!---->'
         )
       }).thenWaitFor(_next => { next = _next }).then(() => {
         expect(vm.$el.innerHTML).toBe('<!---->')
@@ -331,7 +331,7 @@ describe('Component keep-alive', () => {
         assertHookCalls(two, [1, 1, 1, 1, 0])
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test test-enter-active">one</div>'
+          '<div class="test test-enter-active test-enter-to">one</div>'
         )
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.innerHTML).toBe(
@@ -376,7 +376,7 @@ describe('Component keep-alive', () => {
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
           '<div class="test">one</div>' +
-          '<div class="test test-enter-active">two</div>'
+          '<div class="test test-enter-active test-enter-to">two</div>'
         )
       }).thenWaitFor(_next => { next = _next }).then(() => {
         expect(vm.$el.innerHTML).toBe(
@@ -390,7 +390,7 @@ describe('Component keep-alive', () => {
         )
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test test-leave-active">one</div>' +
+          '<div class="test test-leave-active test-leave-to">one</div>' +
           '<div class="test">two</div>'
         )
       }).thenWaitFor(duration + buffer).then(() => {
@@ -411,7 +411,7 @@ describe('Component keep-alive', () => {
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
           '<div class="test">two</div>' +
-          '<div class="test test-enter-active">one</div>'
+          '<div class="test test-enter-active test-enter-to">one</div>'
         )
       }).thenWaitFor(_next => { next = _next }).then(() => {
         expect(vm.$el.innerHTML).toBe(
@@ -425,7 +425,7 @@ describe('Component keep-alive', () => {
         )
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test test-leave-active">two</div>' +
+          '<div class="test test-leave-active test-leave-to">two</div>' +
           '<div class="test">one</div>'
         )
       }).thenWaitFor(duration + buffer).then(() => {
@@ -465,7 +465,7 @@ describe('Component keep-alive', () => {
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
           '<div class="test">one</div>' +
-          '<div class="test test-enter-active">two</div>'
+          '<div class="test test-enter-active test-enter-to">two</div>'
         )
         // switch again before enter finishes,
         // this cancels both enter and leave.
@@ -481,7 +481,7 @@ describe('Component keep-alive', () => {
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
           '<div class="test">two</div>' +
-          '<div class="test test-enter-active">one</div>'
+          '<div class="test test-enter-active test-enter-to">one</div>'
         )
       }).thenWaitFor(_next => { next = _next }).then(() => {
         expect(vm.$el.innerHTML).toBe(
@@ -495,7 +495,7 @@ describe('Component keep-alive', () => {
         )
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test test-leave-active">two</div>' +
+          '<div class="test test-leave-active test-leave-to">two</div>' +
           '<div class="test">one</div>'
         )
       }).thenWaitFor(duration + buffer).then(() => {
@@ -532,8 +532,8 @@ describe('Component keep-alive', () => {
         )
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test v-leave-active">foo</div>' +
-          '<div class="test test-enter-active">bar</div>'
+          '<div class="test v-leave-active v-leave-to">foo</div>' +
+          '<div class="test test-enter-active test-enter-to">bar</div>'
         )
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.innerHTML).toBe(
@@ -547,8 +547,8 @@ describe('Component keep-alive', () => {
         )
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test test-leave-active">bar</div>' +
-          '<div class="test v-enter-active">foo</div>'
+          '<div class="test test-leave-active test-leave-to">bar</div>' +
+          '<div class="test v-enter-active v-enter-to">foo</div>'
         )
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.innerHTML).toBe(

+ 11 - 11
test/unit/features/transition/transition-group.spec.js

@@ -51,8 +51,8 @@ if (!isIE9) {
         expect(vm.$el.innerHTML).toBe(
           `<span>` +
             ['a', 'b', 'c'].map(i => `<div class="test">${i}</div>`).join('') +
-            `<div class="test v-enter-active">d</div>` +
-            `<div class="test v-enter-active">e</div>` +
+            `<div class="test v-enter-active v-enter-to">d</div>` +
+            `<div class="test v-enter-active v-enter-to">e</div>` +
           `</span>`
         )
       }).thenWaitFor(duration + buffer).then(() => {
@@ -78,9 +78,9 @@ if (!isIE9) {
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
           `<span>` +
-            `<div class="test v-leave-active">a</div>` +
+            `<div class="test v-leave-active v-leave-to">a</div>` +
             `<div class="test">b</div>` +
-            `<div class="test v-leave-active">c</div>` +
+            `<div class="test v-leave-active v-leave-to">c</div>` +
           `</span>`
         )
       }).thenWaitFor(duration + buffer).then(() => {
@@ -107,10 +107,10 @@ if (!isIE9) {
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
           `<span>` +
-            `<div class="test v-leave-active">a</div>` +
+            `<div class="test v-leave-active v-leave-to">a</div>` +
             `<div class="test">b</div>` +
             `<div class="test">c</div>` +
-            `<div class="test v-enter-active">d</div>` +
+            `<div class="test v-enter-active v-enter-to">d</div>` +
           `</span>`
         )
       }).thenWaitFor(duration + buffer).then(() => {
@@ -137,10 +137,10 @@ if (!isIE9) {
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
           `<span>` +
-            `<div class="test v-leave-active">a</div>` +
+            `<div class="test v-leave-active v-leave-to">a</div>` +
             `<div class="test">b</div>` +
             `<div class="test">c</div>` +
-            `<div class="test v-enter-active">d</div>` +
+            `<div class="test v-enter-active v-enter-to">d</div>` +
           `</span>`
         )
       }).thenWaitFor(duration + buffer).then(() => {
@@ -163,7 +163,7 @@ if (!isIE9) {
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
           `<span>` +
-            vm.items.map(i => `<div class="test v-enter-active">${i}</div>`).join('') +
+            vm.items.map(i => `<div class="test v-enter-active v-enter-to">${i}</div>`).join('') +
           `</span>`
         )
       }).thenWaitFor(duration + buffer).then(() => {
@@ -270,10 +270,10 @@ if (!isIE9) {
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML.replace(/\s?style=""(\s?)/g, '$1')).toBe(
           `<span>` +
-            `<div class="test group-enter-active">d</div>` +
+            `<div class="test group-enter-active group-enter-to">d</div>` +
             `<div class="test">b</div>` +
             `<div class="test group-move">a</div>` +
-            `<div class="test group-leave-active group-move">c</div>` +
+            `<div class="test group-leave-active group-move group-leave-to">c</div>` +
           `</span>`
         )
       }).thenWaitFor(duration * 2).then(() => {

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

@@ -37,8 +37,8 @@ if (!isIE9) {
         )
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test v-leave-active">one</div>' +
-          '<div class="test v-enter-active">two</div>'
+          '<div class="test v-leave-active v-leave-to">one</div>' +
+          '<div class="test v-enter-active v-enter-to">two</div>'
         )
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.innerHTML).toBe(
@@ -72,7 +72,7 @@ if (!isIE9) {
         )
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test test-leave-active">one</div><!---->'
+          '<div class="test test-leave-active test-leave-to">one</div><!---->'
         )
       }).thenWaitFor(_next => { next = _next }).then(() => {
         expect(vm.$el.innerHTML).toBe('<!---->')
@@ -82,7 +82,7 @@ if (!isIE9) {
         )
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test test-enter-active">two</div>'
+          '<div class="test test-enter-active test-enter-to">two</div>'
         )
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.innerHTML).toBe(
@@ -117,7 +117,7 @@ if (!isIE9) {
         )
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test test-leave-active">one</div><!---->'
+          '<div class="test test-leave-active test-leave-to">one</div><!---->'
         )
         // Force re-render before the element finishes leaving
         // this should not cause the incoming element to enter early
@@ -130,7 +130,7 @@ if (!isIE9) {
         )
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test test-enter-active">two</div>'
+          '<div class="test test-enter-active test-enter-to">two</div>'
         )
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.innerHTML).toBe(
@@ -166,7 +166,7 @@ if (!isIE9) {
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
           '<div class="test">one</div>' +
-          '<div class="test test-enter-active">two</div>'
+          '<div class="test test-enter-active test-enter-to">two</div>'
         )
       }).thenWaitFor(_next => { next = _next }).then(() => {
         expect(vm.$el.innerHTML).toBe(
@@ -180,7 +180,7 @@ if (!isIE9) {
         )
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test test-leave-active">one</div>' +
+          '<div class="test test-leave-active test-leave-to">one</div>' +
           '<div class="test">two</div>'
         )
       }).thenWaitFor(duration + buffer).then(() => {
@@ -216,7 +216,7 @@ if (!isIE9) {
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
           '<div class="test">one</div>' +
-          '<div class="test test-enter-active">two</div>'
+          '<div class="test test-enter-active test-enter-to">two</div>'
         )
         // switch again before enter finishes,
         // this cancels both enter and leave.
@@ -232,7 +232,7 @@ if (!isIE9) {
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
           '<div class="test">two</div>' +
-          '<div class="test test-enter-active">one</div>'
+          '<div class="test test-enter-active test-enter-to">one</div>'
         )
       }).thenWaitFor(_next => { next = _next }).then(() => {
         expect(vm.$el.innerHTML).toBe(
@@ -246,7 +246,7 @@ if (!isIE9) {
         )
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test test-leave-active">two</div>' +
+          '<div class="test test-leave-active test-leave-to">two</div>' +
           '<div class="test">one</div>'
         )
       }).thenWaitFor(duration + buffer).then(() => {
@@ -275,8 +275,8 @@ if (!isIE9) {
         )
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test v-leave-active">one</div>' +
-          '<div class="test v-enter-active">two</div>'
+          '<div class="test v-leave-active v-leave-to">one</div>' +
+          '<div class="test v-enter-active v-enter-to">two</div>'
         )
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.innerHTML).toBe(
@@ -309,7 +309,7 @@ if (!isIE9) {
         )
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test test-leave-active">one</div><!---->'
+          '<div class="test test-leave-active test-leave-to">one</div><!---->'
         )
       }).thenWaitFor(_next => { next = _next }).then(() => {
         expect(vm.$el.innerHTML).toBe('<!---->')
@@ -319,7 +319,7 @@ if (!isIE9) {
         )
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test test-enter-active">two</div>'
+          '<div class="test test-enter-active test-enter-to">two</div>'
         )
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.innerHTML).toBe(
@@ -354,7 +354,7 @@ if (!isIE9) {
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
           '<div class="test">one</div>' +
-          '<div class="test test-enter-active">two</div>'
+          '<div class="test test-enter-active test-enter-to">two</div>'
         )
       }).thenWaitFor(_next => { next = _next }).then(() => {
         expect(vm.$el.innerHTML).toBe(
@@ -368,7 +368,7 @@ if (!isIE9) {
         )
       }).thenWaitFor(nextFrame).then(() => {
         expect(vm.$el.innerHTML).toBe(
-          '<div class="test test-leave-active">one</div>' +
+          '<div class="test test-leave-active test-leave-to">one</div>' +
           '<div class="test">two</div>'
         )
       }).thenWaitFor(duration + buffer).then(() => {

+ 49 - 42
test/unit/features/transition/transition.spec.js

@@ -25,14 +25,14 @@ if (!isIE9) {
       waitForUpdate(() => {
         expect(vm.$el.children[0].className).toBe('test v-leave v-leave-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test v-leave-active')
+        expect(vm.$el.children[0].className).toBe('test v-leave-active v-leave-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children.length).toBe(0)
         vm.ok = true
       }).then(() => {
         expect(vm.$el.children[0].className).toBe('test v-enter v-enter-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test v-enter-active')
+        expect(vm.$el.children[0].className).toBe('test v-enter-active v-enter-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children[0].className).toBe('test')
       }).then(done)
@@ -50,14 +50,14 @@ if (!isIE9) {
       waitForUpdate(() => {
         expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-leave-active')
+        expect(vm.$el.children[0].className).toBe('test test-leave-active test-leave-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children.length).toBe(0)
         vm.ok = true
       }).then(() => {
         expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-enter-active')
+        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)
@@ -70,7 +70,9 @@ if (!isIE9) {
             <transition
               enter-class="hello"
               enter-active-class="hello-active"
+              enter-to-class="hello-to"
               leave-class="bye"
+              leave-to-class="bye-to"
               leave-active-class="byebye active">
               <div v-if="ok" class="test">foo</div>
             </transition>
@@ -85,14 +87,14 @@ if (!isIE9) {
       waitForUpdate(() => {
         expect(vm.$el.children[0].className).toBe('test bye byebye active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test byebye active')
+        expect(vm.$el.children[0].className).toBe('test byebye active bye-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children.length).toBe(0)
         vm.ok = true
       }).then(() => {
         expect(vm.$el.children[0].className).toBe('test hello hello-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test hello-active')
+        expect(vm.$el.children[0].className).toBe('test hello-active hello-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children[0].className).toBe('test')
       }).then(done)
@@ -119,7 +121,7 @@ if (!isIE9) {
       waitForUpdate(() => {
         expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-leave-active')
+        expect(vm.$el.children[0].className).toBe('test test-leave-active test-leave-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children.length).toBe(0)
         vm.ok = true
@@ -127,7 +129,7 @@ if (!isIE9) {
       }).then(() => {
         expect(vm.$el.children[0].className).toBe('test changed-enter changed-enter-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test changed-enter-active')
+        expect(vm.$el.children[0].className).toBe('test changed-enter-active changed-enter-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children[0].className).toBe('test')
       }).then(done)
@@ -143,8 +145,10 @@ if (!isIE9) {
               props: {
                 name: 'inline',
                 enterClass: 'hello',
+                enterToClass: 'hello-to',
                 enterActiveClass: 'hello-active',
                 leaveClass: 'bye',
+                leaveToClass: 'bye-to',
                 leaveActiveClass: 'byebye active'
               },
               on: {
@@ -164,7 +168,7 @@ if (!isIE9) {
         expect(vm.$el.children[0].className).toBe('test bye byebye active')
         expect(leave).toHaveBeenCalled()
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test byebye active')
+        expect(vm.$el.children[0].className).toBe('test byebye active bye-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children.length).toBe(0)
         vm.ok = true
@@ -172,7 +176,7 @@ if (!isIE9) {
         expect(vm.$el.children[0].className).toBe('test hello hello-active')
         expect(enter).toHaveBeenCalled()
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test hello-active')
+        expect(vm.$el.children[0].className).toBe('test hello-active hello-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children[0].className).toBe('test')
       }).then(done)
@@ -234,7 +238,7 @@ if (!isIE9) {
         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')
+        expect(vm.$el.children[0].className).toBe('test test-leave-active test-leave-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(afterLeaveSpy).toHaveBeenCalledWith(_el)
         expect(vm.$el.children.length).toBe(0)
@@ -246,7 +250,7 @@ if (!isIE9) {
         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')
+        expect(vm.$el.children[0].className).toBe('test test-enter-active test-enter-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(afterEnterSpy).toHaveBeenCalledWith(_el)
         expect(vm.$el.children[0].className).toBe('test')
@@ -319,7 +323,7 @@ if (!isIE9) {
         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')
+        expect(vm.$el.children[0].className).toBe('test test-leave-active test-leave-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(afterLeaveSpy).toHaveBeenCalledWith(_el)
         expect(vm.$el.children[0].style.display).toBe('none')
@@ -331,7 +335,7 @@ if (!isIE9) {
         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')
+        expect(vm.$el.children[0].className).toBe('test test-enter-active test-enter-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(afterEnterSpy).toHaveBeenCalledWith(_el)
         expect(vm.$el.children[0].className).toBe('test')
@@ -360,9 +364,9 @@ if (!isIE9) {
       waitForUpdate(() => {
         expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-leave-active')
+        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 test-leave-active')
+        expect(vm.$el.children[0].className).toBe('test test-leave-active test-leave-to')
         expect(next).toBeTruthy()
         next()
         expect(vm.$el.children.length).toBe(0)
@@ -371,9 +375,9 @@ if (!isIE9) {
       }).then(() => {
         expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-enter-active')
+        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 test-enter-active')
+        expect(vm.$el.children[0].className).toBe('test test-enter-active test-enter-to')
         expect(next).toBeTruthy()
         next()
         expect(vm.$el.children[0].className).toBe('test')
@@ -456,13 +460,15 @@ if (!isIE9) {
       vm.ok = true
       waitForUpdate(() => {
         expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
+      }).thenWaitFor(nextFrame).then(() => {
+        expect(vm.$el.children[0].className).toBe('test test-enter-active test-enter-to')
       }).thenWaitFor(duration / 2).then(() => {
         vm.ok = false
       }).then(() => {
         expect(spy).toHaveBeenCalled()
         expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-leave-active')
+        expect(vm.$el.children[0].className).toBe('test test-leave-active test-leave-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children.length).toBe(0)
       }).then(done)
@@ -495,7 +501,7 @@ if (!isIE9) {
         expect(vm.$el.children.length).toBe(1) // should have removed leaving element
         expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-enter-active')
+        expect(vm.$el.children[0].className).toBe('test test-enter-active test-enter-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.innerHTML).toBe('<div class="test">foo</div>')
       }).then(done)
@@ -521,7 +527,7 @@ if (!isIE9) {
       waitForUpdate(() => {
         expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-leave-active')
+        expect(vm.$el.children[0].className).toBe('test test-leave-active test-leave-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children[0].style.display).toBe('none')
         vm.ok = true
@@ -529,7 +535,7 @@ if (!isIE9) {
         expect(vm.$el.children[0].style.display).toBe('')
         expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-enter-active')
+        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)
@@ -557,7 +563,7 @@ if (!isIE9) {
       waitForUpdate(() => {
         expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-leave-active')
+        expect(vm.$el.children[0].className).toBe('test test-leave-active test-leave-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children[0].style.display).toBe('none')
         vm.ok = true
@@ -565,7 +571,7 @@ if (!isIE9) {
         expect(vm.$el.children[0].style.display).toBe('')
         expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-enter-active')
+        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)
@@ -592,14 +598,14 @@ if (!isIE9) {
       waitForUpdate(() => {
         expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-leave-active')
+        expect(vm.$el.children[0].className).toBe('test test-leave-active test-leave-to')
       }).thenWaitFor(10).then(() => {
         vm.ok = true
       }).then(() => {
         expect(spy).toHaveBeenCalled()
         expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-enter-active')
+        expect(vm.$el.children[0].className).toBe('test test-enter-active test-enter-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children[0].style.display).toBe('')
       }).then(done)
@@ -623,14 +629,14 @@ if (!isIE9) {
       waitForUpdate(() => {
         expect(vm.$el.children[0].className).toBe('test-anim-leave test-anim-leave-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test-anim-leave-active')
+        expect(vm.$el.children[0].className).toBe('test-anim-leave-active test-anim-leave-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children.length).toBe(0)
         vm.ok = true
       }).then(() => {
         expect(vm.$el.children[0].className).toBe('test-anim-enter test-anim-enter-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test-anim-enter-active')
+        expect(vm.$el.children[0].className).toBe('test-anim-enter-active test-anim-enter-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children[0].className).toBe('')
       }).then(done)
@@ -654,19 +660,19 @@ if (!isIE9) {
       waitForUpdate(() => {
         expect(vm.$el.children[0].className).toBe('test test-anim-long-leave test-anim-long-leave-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-anim-long-leave-active')
+        expect(vm.$el.children[0].className).toBe('test test-anim-long-leave-active test-anim-long-leave-to')
       }).thenWaitFor(duration + 5).then(() => {
         // should not end early due to transition presence
-        expect(vm.$el.children[0].className).toBe('test test-anim-long-leave-active')
+        expect(vm.$el.children[0].className).toBe('test test-anim-long-leave-active test-anim-long-leave-to')
       }).thenWaitFor(duration + 5).then(() => {
         expect(vm.$el.children.length).toBe(0)
         vm.ok = true
       }).then(() => {
         expect(vm.$el.children[0].className).toBe('test test-anim-long-enter test-anim-long-enter-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-anim-long-enter-active')
+        expect(vm.$el.children[0].className).toBe('test test-anim-long-enter-active test-anim-long-enter-to')
       }).thenWaitFor(duration + 5).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-anim-long-enter-active')
+        expect(vm.$el.children[0].className).toBe('test test-anim-long-enter-active test-anim-long-enter-to')
       }).thenWaitFor(duration + 5).then(() => {
         expect(vm.$el.children[0].className).toBe('test')
       }).then(done)
@@ -679,6 +685,7 @@ if (!isIE9) {
             <transition name="test"
               appear
               appear-class="test-appear"
+              appear-to-class="test-appear-to"
               appear-active-class="test-appear-active">
               <div v-if="ok" class="test">foo</div>
             </transition>
@@ -690,7 +697,7 @@ if (!isIE9) {
       waitForUpdate(() => {
         expect(vm.$el.children[0].className).toBe('test test-appear test-appear-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-appear-active')
+        expect(vm.$el.children[0].className).toBe('test test-appear-active test-appear-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children[0].className).toBe('test')
       }).then(done)
@@ -711,7 +718,7 @@ if (!isIE9) {
       waitForUpdate(() => {
         expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-enter-active')
+        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)
@@ -735,7 +742,7 @@ if (!isIE9) {
       waitForUpdate(() => {
         expect(vm.$el.childNodes[0].getAttribute('class')).toBe('test v-leave v-leave-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.childNodes[0].getAttribute('class')).toBe('test v-leave-active')
+        expect(vm.$el.childNodes[0].getAttribute('class')).toBe('test v-leave-active v-leave-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.childNodes.length).toBe(1)
         expect(vm.$el.childNodes[0].nodeType).toBe(8) // should be an empty comment node
@@ -744,7 +751,7 @@ if (!isIE9) {
       }).then(() => {
         expect(vm.$el.childNodes[0].getAttribute('class')).toBe('test v-enter v-enter-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.childNodes[0].getAttribute('class')).toBe('test v-enter-active')
+        expect(vm.$el.childNodes[0].getAttribute('class')).toBe('test v-enter-active v-enter-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.childNodes[0].getAttribute('class')).toBe('test')
       }).then(done)
@@ -777,14 +784,14 @@ if (!isIE9) {
       waitForUpdate(() => {
         expect(vm.$el.children[0].className).toBe('test v-leave v-leave-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test v-leave-active')
+        expect(vm.$el.children[0].className).toBe('test v-leave-active v-leave-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children.length).toBe(0)
         vm.ok = true
       }).then(() => {
         expect(vm.$el.children[0].className).toBe('test v-enter v-enter-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test v-enter-active')
+        expect(vm.$el.children[0].className).toBe('test v-enter-active v-enter-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children[0].className).toBe('test')
       }).then(done)
@@ -815,14 +822,14 @@ if (!isIE9) {
       waitForUpdate(() => {
         expect(vm.$el.children[0].className).toBe('test v-leave v-leave-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test v-leave-active')
+        expect(vm.$el.children[0].className).toBe('test v-leave-active v-leave-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children.length).toBe(0)
         vm.ok = true
       }).then(() => {
         expect(vm.$el.children[0].className).toBe('test v-enter v-enter-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test v-enter-active')
+        expect(vm.$el.children[0].className).toBe('test v-enter-active v-enter-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children[0].className).toBe('test')
       }).then(done)
@@ -849,14 +856,14 @@ if (!isIE9) {
       waitForUpdate(() => {
         expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-leave-active')
+        expect(vm.$el.children[0].className).toBe('test test-leave-active test-leave-to')
       }).thenWaitFor(duration + buffer).then(() => {
         expect(vm.$el.children.length).toBe(0)
         vm.ok = true
       }).then(() => {
         expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
       }).thenWaitFor(nextFrame).then(() => {
-        expect(vm.$el.children[0].className).toBe('test test-enter-active')
+        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)