本文基於vue官方文檔,分別爲:動態組件 & 異步組件、插槽、進入/離開 & 列表過渡 章節連接描述html
要想實現tab動畫,首先要了解vue中哪些元素/那些組件適合在那些條件下實現動畫效果
vue官方文檔中有這樣一個例子vue
<div id="demo"> <button v-on:click="show = !show"> Toggle </button> <transition name="fade"><!--用transition包裹要添加動畫的元素/組件--> <p v-if="show">hello</p> </transition> </div>
當你在transition上添加指定的name後,vue在進入/離開的過渡中,會有 6 個 class 切換,分別爲:
name-enter、name-enter-active、name-enter-to、name-leave、name-leave-active、name-leave-togit
如圖所示:github
v-enter:定義進入過渡的開始狀態。在元素被插入以前生效,在元素被插入以後的下一幀移除。v-enter-active:定義進入過渡生效時的狀態。在整個進入過渡的階段中應用,在元素被插入以前生效,在過渡/動畫完成以後移除。這個類能夠被用來定義進入過渡的過程時間,延遲和曲線函數。數組
v-enter-to: 2.1.8版及以上 定義進入過渡的結束狀態。在元素被插入以後下一幀生效 (與此同時 v-enter
被移除),在過渡/動畫完成以後移除。緩存v-leave: 定義離開過渡的開始狀態。在離開過渡被觸發時馬上生效,下一幀被移除。異步
v-leave-active:定義離開過渡生效時的狀態。在整個離開過渡的階段中應用,在離開過渡被觸發時馬上生效,在過渡/動畫完成以後移除。這個類能夠被用來定義離開過渡的過程時間,延遲和曲線函數。ide
v-leave-to: 2.1.8版及以上 定義離開過渡的結束狀態。在離開過渡被觸發以後下一幀生效 (與此同時 v-leave
被刪除),在過渡/動畫完成以後移除。函數
因此咱們要想實現tab切換動畫,只須要在transition中添加咱們每一個單獨tab頁的子組件動畫
1.用ul(無序列表)建立tab上方導航
<ul class="tabNav"> <li v-for="(item, index) in tabs" :class="{'active' : tabIndex === index}" @click="changeTab(index)">{{item.desc}}</li> </ul>
data中的定義
data () { return { currentTabComponent: 'tab1', // tab頁默認顯示第一項 tabIndex: 0, transitionName: '' // tab根據既定格式定義 tabs: [ { id: 'tab1', desc: '首頁' }, { id: 'tab2', desc: '聯繫咱們' }, { id: 'tab3', desc: '與我相關' } ] } },
設置li橫向排布,我建立的時候是把每一個導航名稱放在data裏,用v-for作循環
2.具體設置每一個tab頁
<!-- slot中間表示插槽內容爲空時顯示的默認值 -->
<!-- 每個tab頁的展現, keep-alive使得標籤的組件實例可以在它們第一次被建立的時候緩存下來-->
<div class="content"> <keep-alive> <transition :name="transitionName"> <component v-bind:is="currentTabComponent"></component> </transition> </keep-alive> </div>
組件功能是vue項目的一大特點。組件能夠擴展html元素,能夠封裝可重用的代碼。咱們用is特性來擴展,從而達到能夠在這些受限制的html元素中使用。is會將currentTabComponent的值轉換成指定的組件形式:
若是currentTabComponent爲my-component
<component v-bind:is="currentTabComponent"></component>
轉化後爲:<my-component></mu-component>
在tab導航點擊時修改tabIndex,此時監聽tabIndex的變化,當目的值>原始值,向右滑動,反之向左滑動
tabIndex (to, from) {
let that = this;
that.transitionName = (to > from) ? 'forward' : 'backward';
}
設置vue動畫六個狀態的class的效果,此項目中由於存在兩種滑動狀態,因此有12個class
.forward-enter-active,.forward-leave-active{ transition: 0.5s all ease; transform: translateX(0); } .forward-enter{ transform: translateX(100%); } .forward-enter-to{ transform: translateX(0); } .forward-leave { transform: translate3d(0, 0, 0); } .forward-leave-to { transform: translate3d(-100%, 0, 0); } .backward-enter-active, .backward-leave-active { transition: all 0.5s; } .backward-leave { transform: translate3d(0, 0, 0); } .backward-leave-to { transform: translate3d(100%, 0, 0); } .backward-enter { transform: translate3d(-100%, 0, 0); } .backward-enter-to { transform: translate3d(0, 0, 0); }
遇到問題:
在兩個tab頁相互切換時,當前div沒被移走,將會致使下一個將會一直存在於當前div消失才一上來,因此我用了position:absolute,使每一個div都飄在上面,可是遇到的問題是最外層的盒子不能隨內層單個tab頁高度變化,因此我用了js動態把tab頁高度賦值給外層div,目前還沒想到更好的方案。
最後我封裝了一下組件,使用時只須要傳入tab的標題數組和單獨的tab頁便可使用
⚠️:github地址可查看代碼github