過渡效果
SPA 中組件的切換有一種生硬的隱藏顯示感覺,為了更好的用戶體驗,讓組件切換時淡出淡入,Vue 提供了專門的組件 transition。
過濾效果應用場景
- 條件渲染 (使用 v-if)
- 條件展示 (使用 v-show)
- 動態組件
- 組件根節點
過渡狀態
- enter:定義進入過渡的開始狀態。在元素被插入時生效。
- endter-active:定義過渡的狀態。在元素整個過渡過程中作用,在元素被插入時生效。
- enter-to: 2.1.8版及以上 定義進入過渡的結束狀態。
- leave:定義離開過渡的開始狀態。在離開過渡被觸發時生效。
- leave-active:定義過渡的狀態。在元素整個過渡過程中作用,在離開過渡被觸發后立即生效。
- leave-to: 2.1.8版及以上 定義離開過渡的結束狀態。
每個狀態在使用的時候都是在 CSS 中使用,結合組件 transition 的 name 屬性。如 <transition name="fade"></transition>
,對應的是 fade-
加上每個狀態:fade-enter
。
CSS 過渡
使用到組件 transition
的屬性: name
。
<style type="text/css" media="screen">/*初始狀態*/.fade-enter{opacity: 0;}/*已經準備就緒*/.fade-enter-active{transition: all .5s;}/*已經消失*/.fade-leave-active{opacity: 0; transition: all .5s;}
</style><div id="app"><input type="button" :value="show ? 'hide' : 'show'" @click="show = !show" /><br/><transition name="fade"><img src="imgs/green.jpg" v-show="show" /></transition>
</div><script type="text/javascript">var vm = new Vue({el: '#app',data: {show: true}})
</script>
效果預覽
CSS 動畫
使用到組件 transition
的屬性: name
。
<style type="text/css" media="screen">.fade-enter-active{animation: fade-in .5s;}.fade-leave-active{animation: fade-out .5s;}@keyframes fade-in{from{opacity: 0;}to{opacity: 1;}}@keyframes fade-out{from{opacity: 1;}to{opacity: 0;}}
</style><div id="app"><input type="button" :value="show ? 'hide' : 'show'" @click="show = !show" /><br/><transition name="fade"><img src="imgs/green.jpg" v-if="show" /></transition>
</div><script type="text/javascript">var vm = new Vue({el: '#app',data: {show: true}})
</script>
效果預覽
初始渲染的過濾
第一次加載時的過渡效果,使用到組件 transition
的屬性: appear
appear-class
appear-active-class
。
<style type="text/css" media="screen">.fade-enter{opacity: 0;}.fade-enter-active{transition: all 3s;}
</style><div id="app"><transition appear appear-class="fade-enter" appear-active-class="fade-enter-active"><img src="imgs/green.jpg" /></transition>
</div><script type="text/javascript">var vm = new Vue({el: '#app'})
</script>
效果預覽
多個元素的過河效果
同時生效的進入和離開的過渡不能滿足所有要求,所以 Vue 提供了 過渡模式:
- in-out:新元素先進行過渡,完成之后當前元素過渡離開。
- out-in:當前元素先進行過渡,完成之后新元素過渡進入。
使用到組件 transition
的屬性: mode
。
<style type="text/css" media="screen">.fade-enter{opacity: 0;}.fade-enter-active{transition: all .5s;}.fade-leave-active{opacity: 0; transition: all .5s;}
</style><div id="app"><fieldset><legend><h3>mode = in-out</h3></legend><div><input type="button" :value="red ? 'green' : 'red'" @click="red = !red" /><br/><transition name="fade" mode="in-out"> <img src="imgs/red.jpg" v-if="red" key="red"/><img src="imgs/green.jpg" v-else key="green"/></transition> </div></fieldset><fieldset><legend><h3>mode = out-in</h3></legend><div><input type="button" :value="flag == 1 ? 'green' : flag == 2 ? 'yellw' : 'red'" @click="flag = flag == 1 ? 2 : flag == 2 ? 3 : 1" /><br/><transition name="fade" mode="out-in"> <img src="imgs/red.jpg" v-if="flag == 1" key="red"/><img src="imgs/green.jpg" v-else-if="flag == 2" key="green"/><img src="imgs/yellow.jpg" v-else key="yellow" /></transition> </div></fieldset>
</div><script type="text/javascript">var vm = new Vue({el: '#app',data: {red: true,flag: 1}})
</script>
效果預覽
列表(v-for)的過渡效果
v-for 生成列表過渡效果要使用組件 transition-group
,組件提供屬性 tag
表示該組件將會渲染成對應的 DOM 節點,其它的使用和 transition
一樣。
<style type="text/css" media="screen">*{list-style: none;}li{width: 300px; margin-bottom: 5px; padding: 10px 20px; background-color: #ccc;}.list-enter{opacity: 0; transform: translateX(300px);}.list-enter-active{transition: all .5s;}.list-leave-active{transition: all .5s; opacity: 0; transform: translateX(-300px);}
</style><div id="app"><p><input type="button" value="AddItem" @click="addItem"><input type="button" value="RemoveItem" @click="removeItem"></p><transition-group tag="ul" name="list"><li v-for="(item, index) in items" :key="item">Item {{index}}</li></transition-group>
</div><script type="text/javascript">var vm = new Vue({el: '#app',data: {items: [1,2,3]},methods: {randomIndex: function(){return parseInt(this.items.length * Math.random());},addItem: function(){this.items.splice(this.randomIndex(), 0, this.items.length + 1);},removeItem: function(){this.items.splice(this.randomIndex(), 1);}}})
</script>
效果預覽
自定義過渡的類名
我們可以通過以下特性來自定義過渡類名:
- enter-class
- enter-active-class
- enter-to-class (2.1.8+)
- leave-class
- leave-active-class
- leave-to-class (2.1.8+)
他們的優先級高于普通的類名,這對于 Vue 的過渡系統和其他第三方 CSS 動畫庫,如 Animate.css 結合使用十分有用。
<link rel="stylesheet" type="text/css" href="animate.css"><div id="app"><button @click="show = !show">Toggle render</button><transition enter-active-class="animated jello" leave-active-class="animated bounceOutRight"><div v-if="show"><img src="./imgs/green.jpg" /></div></transition>
</div><script type="text/javascript">var vm = new Vue({el: '#app',data: {show: true}})
</script>
效果預覽
過渡效果鉤子函數
除了用CSS過渡的動畫來實現vue的組件過渡,還可以用JavaScript的鉤子函數來實現,在鉤子函數中直接操作DOM。我們可以在屬性中聲明以下鉤子:
<transitionv-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>
<script type="text/javascript">var vm = new Vue({el: '#app',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) {// ...}}})
</script>