Vue2.0的過渡系統(transition)有了很大的改變,想把1.0的項目遷移到2.0,著實需要費一些功夫,今天我就要把vue2.0的過渡系統的用法搞清楚,因為之前確實踩了不少坑。這里只涉及單元素/組件的過渡實現,vue2.0的文檔中還講到了初始渲染的過渡、多個元素的過渡、多個組件的過渡和列表過渡,他們的過渡效果實現方式和單元素/組件的類似,我感覺實際項目中用的不太多吧,有興趣的同學可以去了解一下,文檔這里說的多個元素和多個組件和我們的理解可能不太一樣,一定要仔細閱讀文檔,搞清楚到底說的是什么樣的情況。
什么是過渡
Vue只有在插入,更新或者移除DOM元素時才會應用過渡效果,過渡效果的應用可以通過不同方式實現,官方文檔中提到了如下幾種:
- 在CSS過渡和動畫中自動應用class;
- 配合使用第三方的CSS動畫庫,如Animate.css;
- 在過渡鉤子函數中使用JavaScript直接操作DOM;
- 配合使用第三方JavaScript動畫庫,如Velocity;
上面四種方式其實主要就是兩種,一個是利用CSS過渡或者動畫,另一個是利用JavaScript鉤子函數。
怎么應用過渡到元素/組件上
要想使元素或者組件應用到我們所寫的過渡動畫,需要使用vue提供的transition來封裝組件成為過渡組件,transition需要與如下情景中的任一種一起使用:
- v-if(條件渲染)
- v-show(條件展示)
- 動態組件
- 在組建的根節點上,并且被vue實例DOM方法觸發,如appendTo方法把組件添加到某個根節點上
當需要插入或者刪除封裝成過渡元素的元素時,vue將做如下事情:
- 查找目標元素是否有CSS過渡或者動畫,如果有就在適當的時候進行處理;
- 如果過渡組件設置了JavaScript鉤子函數,vue會在相應階段調用鉤子函數;
- 如果以上兩者都沒有,DOM操作(插入或者刪除)就在下一幀立即執行。
CSS過渡
先舉一個典型的CSS過渡的例子:
<!-- 首先將要過渡的元素用transition包裹,并設置過渡的name,然后添加觸發這個元素過渡的按鈕(實際項目中不一定是按鈕,任何能觸發過渡組件的DOM操作的操作都可以) -->
<div>
<button @click="show=!show">show</button>
<transition name="fade">
<p v-show="show">hello</p>
</transition>
</div>
// 接著為過渡類名添加規則
&.fade-enter-active, &.fade-leave-active
transition: all 0.5s ease
&.fade-enter, &.fade-leave-active
opacity: 0
封裝上面的代碼,就可以實現一個簡單的動畫了,CSS的transition屬性是用來設置過渡總體效果的,具體可參考:http://www.w3cplus.com/content/css3-transition。
CSS過渡類名
組件過渡過程中,會有四個CSS類名進行切換,這四個類名與上面transition的name屬性有關,比如name="fade",會有如下四個CSS類名:
- fade-enter:進入過渡的開始狀態,元素被插入時生效,只應用一幀后立即刪除;
- fade-enter-active:進入過渡的結束狀態,元素被插入時就生效,在過渡過程完成之后移除;
- fade-leave:離開過渡的開始狀態,元素被刪除時觸發,只應用一幀后立即刪除;
- fade-leave-active:離開過渡的結束狀態,元素被刪除時生效,離開過渡完成之后被刪除;
從上面四個類名可以看出,fade-enter-active和fade-leave-active在整個進入或離開過程中都有效,所以CSS的transition屬性在這兩個類下進行設置。
上面示例中,fade-enter和fade-leave-active類設置CSS為opacity:0,說明過渡剛進入和離開的時候透明度為0,即不顯示。當然還可以設置其他的CSS屬性,transform屬性是除了opacity之外經常在這里被用到的,transform用法可參考http://www.w3cplus.com/content/css3-transition
CSS動畫
組件過渡的實現不僅可以通過CSS過渡還可以通過CSS動畫(animation)實現,建議先了解一下CSS3 Animation,這里還是給個例子:
<div>
<button @click="show=!show">show</button>
<transition name="fold">
<p v-show="show">hello</p>
</transition>
</div>
.fold-enter-active {
animation-name: fold-in;
animation-duration: .5s;
}
.fold-leave-active {
animation-name: fold-out;
animation-duration: .5s;
}
@keyframes fold-in {
0% {
transform: translate3d(0, 100%, 0);
}
50% {
transform: translate3d(0, 50%, 0);
}
100% {
transform: translate3d(0, 0, 0);
}
}
@keyframes fold-out {
0% {
transform: translate3d(0, 0, 0);
}
50% {
transform: translate3d(0, 50%, 0);
}
100% {
transform: translate3d(0, 100%, 0);
}
}
如果預先了解了CSS動畫(上面給了鏈接),上面代碼還是很好理解的,要注意的是CSS動畫中,fold-enter類名在節點插入DOM后不會立即刪除,而是在animationed事件觸發時刪除。
自定義過渡類名
上面的四個過渡類名都是根據transition的name屬性自動生成的,那么能否自己定義這四個類名呢?答案是可以的,通過enter-class、enter-active-class、leave-class、leave-active-class這四個特性來定義。
<div>
<button @click="show=!show">show</button>
<transition
name="fade"
enter-class="fade-in-enter"
enter-active-class="fade-in-active"
leave-class="fade-out-enter"
leave-active-class="fade-out-active"
>
<p v-show="show">hello</p>
</transition>
</div>
&.fade-in-active, &.fade-out-active
transition: all 0.5s ease
&.fade-in-enter, &.fade-out-active
opacity: 0
上面代碼中,原來默認的fade-enter類對應fade-in-enter,fade-enter-active類對應fade-in-active,依次類推。
JavaScript鉤子函數
除了用CSS過渡的動畫來實現vue的組件過渡,還可以用JavaScript的鉤子函數來實現,在鉤子函數中直接操作DOM。我們可以在屬性中聲明以下鉤子:
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:enter-cancelled="enterCancelled"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-on:leave-cancelled="leaveCancelled"
>
</transition>
methods: {
// 過渡進入
// 設置過渡進入之前的組件狀態
beforeEnter: function (el) {
// ...
},
// 設置過渡進入完成時的組件狀態
enter: function (el, done) {
// ...
done()
},
// 設置過渡進入完成之后的組件狀態
afterEnter: function (el) {
// ...
},
enterCancelled: function (el) {
// ...
},
// 過渡離開
// 設置過渡離開之前的組件狀態
beforeLeave: function (el) {
// ...
},
// 設置過渡離開完成時地組件狀態
leave: function (el, done) {
// ...
done()
},
// 設置過渡離開完成之后的組件狀態
afterLeave: function (el) {
// ...
},
// leaveCancelled 只用于 v-show 中
leaveCancelled: function (el) {
// ...
}
}
上面的鉤子函數中可以進行任何你想做的DOM操作。
小技巧:如果你只想設置組件過渡進入的效果而不想有組件過渡離開的效果,這時你就可以用鉤子函數,只設置beforeEnter、enter、afterEnter這幾個鉤子函數就可以了。
目前接觸到的關于vue transition相關的就這么多了,當然vue transition的用法可不止這么點,這需要我以后的慢慢積累。