Vue2.0的過渡系統(tǒng)(transition)有了很大的改變,想把1.0的項(xiàng)目遷移到2.0,著實(shí)需要費(fèi)一些功夫哮塞,今天我就要把vue2.0的過渡系統(tǒng)的用法搞清楚南蹂,因?yàn)橹按_實(shí)踩了不少坑佃乘。這里只涉及單元素/組件的過渡實(shí)現(xiàn)局蚀,vue2.0的文檔中還講到了初始渲染的過渡、多個(gè)元素的過渡恕稠、多個(gè)組件的過渡和列表過渡琅绅,他們的過渡效果實(shí)現(xiàn)方式和單元素/組件的類似,我感覺實(shí)際項(xiàng)目中用的不太多吧鹅巍,有興趣的同學(xué)可以去了解一下千扶,文檔這里說的多個(gè)元素和多個(gè)組件和我們的理解可能不太一樣,一定要仔細(xì)閱讀文檔骆捧,搞清楚到底說的是什么樣的情況澎羞。
什么是過渡
Vue只有在插入,更新或者移除DOM元素時(shí)才會(huì)應(yīng)用過渡效果敛苇,過渡效果的應(yīng)用可以通過不同方式實(shí)現(xiàn)妆绞,官方文檔中提到了如下幾種:
- 在CSS過渡和動(dòng)畫中自動(dòng)應(yīng)用class;
- 配合使用第三方的CSS動(dòng)畫庫枫攀,如Animate.css括饶;
- 在過渡鉤子函數(shù)中使用JavaScript直接操作DOM;
- 配合使用第三方JavaScript動(dòng)畫庫来涨,如Velocity图焰;
上面四種方式其實(shí)主要就是兩種,一個(gè)是利用CSS過渡或者動(dòng)畫蹦掐,另一個(gè)是利用JavaScript鉤子函數(shù)技羔。
怎么應(yīng)用過渡到元素/組件上
要想使元素或者組件應(yīng)用到我們所寫的過渡動(dòng)畫,需要使用vue提供的transition來封裝組件成為過渡組件卧抗,transition需要與如下情景中的任一種一起使用:
- v-if(條件渲染)
- v-show(條件展示)
- 動(dòng)態(tài)組件
- 在組建的根節(jié)點(diǎn)上藤滥,并且被vue實(shí)例DOM方法觸發(fā),如appendTo方法把組件添加到某個(gè)根節(jié)點(diǎn)上
當(dāng)需要插入或者刪除封裝成過渡元素的元素時(shí)社裆,vue將做如下事情:
- 查找目標(biāo)元素是否有CSS過渡或者動(dòng)畫拙绊,如果有就在適當(dāng)?shù)臅r(shí)候進(jìn)行處理;
- 如果過渡組件設(shè)置了JavaScript鉤子函數(shù)浦马,vue會(huì)在相應(yīng)階段調(diào)用鉤子函數(shù)时呀;
- 如果以上兩者都沒有张漂,DOM操作(插入或者刪除)就在下一幀立即執(zhí)行晶默。
CSS過渡
先舉一個(gè)典型的CSS過渡的例子:
<!-- 首先將要過渡的元素用transition包裹,并設(shè)置過渡的name航攒,然后添加觸發(fā)這個(gè)元素過渡的按鈕(實(shí)際項(xiàng)目中不一定是按鈕磺陡,任何能觸發(fā)過渡組件的DOM操作的操作都可以) -->
<div>
<button @click="show=!show">show</button>
<transition name="fade">
<p v-show="show">hello</p>
</transition>
</div>
// 接著為過渡類名添加規(guī)則
&.fade-enter-active, &.fade-leave-active
transition: all 0.5s ease
&.fade-enter, &.fade-leave-active
opacity: 0
封裝上面的代碼,就可以實(shí)現(xiàn)一個(gè)簡單的動(dòng)畫了,CSS的transition屬性是用來設(shè)置過渡總體效果的币他,具體可參考:http://www.w3cplus.com/content/css3-transition坞靶。
CSS過渡類名
組件過渡過程中,會(huì)有四個(gè)CSS類名進(jìn)行切換蝴悉,這四個(gè)類名與上面transition的name屬性有關(guān)彰阴,比如name="fade",會(huì)有如下四個(gè)CSS類名:
- fade-enter:進(jìn)入過渡的開始狀態(tài)拍冠,元素被插入時(shí)生效尿这,只應(yīng)用一幀后立即刪除;
- fade-enter-active:進(jìn)入過渡的結(jié)束狀態(tài)庆杜,元素被插入時(shí)就生效射众,在過渡過程完成之后移除;
- fade-leave:離開過渡的開始狀態(tài)晃财,元素被刪除時(shí)觸發(fā)叨橱,只應(yīng)用一幀后立即刪除;
- fade-leave-active:離開過渡的結(jié)束狀態(tài)断盛,元素被刪除時(shí)生效罗洗,離開過渡完成之后被刪除;
從上面四個(gè)類名可以看出钢猛,fade-enter-active和fade-leave-active在整個(gè)進(jìn)入或離開過程中都有效栖博,所以CSS的transition屬性在這兩個(gè)類下進(jìn)行設(shè)置。
上面示例中厢洞,fade-enter和fade-leave-active類設(shè)置CSS為opacity:0仇让,說明過渡剛進(jìn)入和離開的時(shí)候透明度為0,即不顯示躺翻。當(dāng)然還可以設(shè)置其他的CSS屬性丧叽,transform屬性是除了opacity之外經(jīng)常在這里被用到的,transform用法可參考http://www.w3cplus.com/content/css3-transition
CSS動(dòng)畫
組件過渡的實(shí)現(xiàn)不僅可以通過CSS過渡還可以通過CSS動(dòng)畫(animation)實(shí)現(xiàn)公你,建議先了解一下CSS3 Animation踊淳,這里還是給個(gè)例子:
<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);
}
}
如果預(yù)先了解了CSS動(dòng)畫(上面給了鏈接),上面代碼還是很好理解的陕靠,要注意的是CSS動(dòng)畫中迂尝,fold-enter類名在節(jié)點(diǎn)插入DOM后不會(huì)立即刪除,而是在animationed事件觸發(fā)時(shí)刪除剪芥。
自定義過渡類名
上面的四個(gè)過渡類名都是根據(jù)transition的name屬性自動(dòng)生成的垄开,那么能否自己定義這四個(gè)類名呢?答案是可以的税肪,通過enter-class溉躲、enter-active-class榜田、leave-class、leave-active-class這四個(gè)特性來定義锻梳。
<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
上面代碼中箭券,原來默認(rèn)的fade-enter類對(duì)應(yīng)fade-in-enter,fade-enter-active類對(duì)應(yīng)fade-in-active疑枯,依次類推辩块。
JavaScript鉤子函數(shù)
除了用CSS過渡的動(dòng)畫來實(shí)現(xiàn)vue的組件過渡,還可以用JavaScript的鉤子函數(shù)來實(shí)現(xiàn)荆永,在鉤子函數(shù)中直接操作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: {
// 過渡進(jìn)入
// 設(shè)置過渡進(jìn)入之前的組件狀態(tài)
beforeEnter: function (el) {
// ...
},
// 設(shè)置過渡進(jìn)入完成時(shí)的組件狀態(tài)
enter: function (el, done) {
// ...
done()
},
// 設(shè)置過渡進(jìn)入完成之后的組件狀態(tài)
afterEnter: function (el) {
// ...
},
enterCancelled: function (el) {
// ...
},
// 過渡離開
// 設(shè)置過渡離開之前的組件狀態(tài)
beforeLeave: function (el) {
// ...
},
// 設(shè)置過渡離開完成時(shí)地組件狀態(tài)
leave: function (el, done) {
// ...
done()
},
// 設(shè)置過渡離開完成之后的組件狀態(tài)
afterLeave: function (el) {
// ...
},
// leaveCancelled 只用于 v-show 中
leaveCancelled: function (el) {
// ...
}
}
上面的鉤子函數(shù)中可以進(jìn)行任何你想做的DOM操作。
小技巧:如果你只想設(shè)置組件過渡進(jìn)入的效果而不想有組件過渡離開的效果屁魏,這時(shí)你就可以用鉤子函數(shù)滔以,只設(shè)置beforeEnter、enter氓拼、afterEnter這幾個(gè)鉤子函數(shù)就可以了你画。
目前接觸到的關(guān)于vue transition相關(guān)的就這么多了,當(dāng)然vue transition的用法可不止這么點(diǎn)桃漾,這需要我以后的慢慢積累坏匪。