我們在做移動端項目的時候,底部導航欄基本可以說是必備的功能,可以方便用戶在幾大基本頁面間切換。一套完整的底部導航欄,不僅需要具有導航菜單的顯示,還需要根據實際業務邏輯判斷導航欄何時顯示、何時隱藏,以及在組件之間進行切換時,添加恰當的頁面過渡效果,從而實現整體效果的提升。
比如從 Home 組件跳轉到 Cart 組件時,通過 v-enter、v-leave-to、v-enter-active、v-leave-active 等結合 opacity 屬性,設置組件進入、離開時的透明度過渡效果。再進一步,在定義路由時,通過 meta 參數,設置每條路由的 index 參數,通過監聽 to、 from 路由對象的 index,並比較t o.meta.index 與 from.meta.index ,前者大頁面過渡效果為頁面向左滑動,若后者大則過渡效果為頁面向右滑動,在 App.vue 中設置好之后,也就為后面的組件提供了非常好的過渡效果。
這些內容都會在文章中給出代碼解決方案。
效果截圖:

主要內容 ( Vant版本:2.9.1 ):
1、將底部導航欄單獨封裝,位於:src\components\FooterNav.vue :
2、將 FooterNav 組件引入 App.vue ,以實現全局引用。
3、設置過渡效果
1、FooterNav.vue 文件
1.1 引入 Tabbar:
import { Tabbar, TabbarItem } from 'vant';
1.2 組件注冊:
components: {
[Tabbar.name]: Tabbar,
[TabbarItem.name]: TabbarItem,
},
1.3 設置初始選中標簽:
data() { return { active: 'home' } },
1.4 在 <template></template> 中添加:
<van-tabbar v-model="active" > <van-tabbar-item name="home" icon="home-o">標簽</van-tabbar-item> <van-tabbar-item name="category" icon="search">標簽</van-tabbar-item> <van-tabbar-item name="shop-cart" icon="friends-o">標簽</van-tabbar-item> <van-tabbar-item name="setting" icon="setting-o">標簽</van-tabbar-item> </van-tabbar>
2、引入 App.vue
2.1 引入:
import FooterNav from './components/FooterNav.vue';
2.2 組件注冊:
components: { "footer-nav": FooterNav, }
注: 組件的名稱使用 kebab-case ( 短橫線分隔命名 ) 命名,可以很好的避免和當前以及未來的 HTML 元素相沖突。
2.3 在 <template></template> 中添加:
<div id="app"> <!-- main 內容 --> <transition :name="mainName"> <keep-alive v-if="$route.meta.keepAlive"> <!-- 這里是會被緩存的視圖組件 --> <router-view id="view" v-if="$route.meta.keepAlive" /> </keep-alive> <!-- 這里是不被緩存的視圖組件 --> <router-view v-if="!$route.meta.keepAlive && isRouterAlive" id="view" /> </transition> <!-- 底部導航 --> <transition :name="navName"> <footer-nav v-if="isShowNav" :activeNavIndex="activeNavIndex"></footer-nav> </transition> </div>
2.4 設置 data:
data() { return { mainName: '', // 內容區域動畫名 navName: '', // 導航動畫名 isShowNav: false, // 是否顯示底部導航 Tab activeNavIndex: 0, // 底部導航激活下標 isRouterAlive: true, // 用於刷新頁面用 navTabs: ['Home', 'Category', 'Cart', 'Me'] // 底部導航 }; },
2.5 設置初始路由
也就是設置剛進入系統時就進入 home 頁面:
watch: { activeNavIndex(newValue) { if(newValue === 0) { this.$router.push('/home') } } }
3.設置過濾效果
3.1 通過 watch 監聽路由改變,設置 transition 名稱:
watch: { $route (to, from) { const {navTabs} = this.$data; const toName = to.name; const fromName = from.name; //如果是在 navTab 頁面內刷新瀏覽器或初始進入系統,則顯示導航欄 if(navTabs.includes(toName) && !fromName) this.isShowNav = true;
switch (toName) {
case 'home': this.activeNavIndex = 0; break;
case 'category': this.activeNavIndex = 1; break;
case 'cart': this.activeNavIndex = 2; break;
case 'user': this.activeNavIndex = 3; break;
} /* 判斷footer-nav是否顯示 * 根據meta.index判斷頁面向左滑動 or 向右滑動 */ // 判斷是否是底部導航之間相互切換 if(navTabs.includes(toName) && navTabs.includes(fromName)) { this.mainName = 'fade'; this.isShowNav = true; // 如果 to 索引大於 from 索引, 判斷為前進狀態, 反之則為后退狀態 } else if (to.meta.index > from.meta.index) { this.mainName = 'slide-left'; this.navName = 'nav-slide'; this.isShowNav = false; } else if (to.meta.index < from.meta.index) { this.mainName = 'slide-right'; this.navName = 'nav-slide'; (navTabs.includes(toName))&&(this.isShowNav = true); } } }
3.2 添加過渡效果:
//底部導航點進其他頁面 導航 tab 動畫 .nav-slide-enter, .nav-slide-leave-to { transform: translate3d(-100%,0,0) } .nav-slide-enter-active, .nav-slide-leave-active { transition: all 5.5s }
// 底部導航之間相互切換 內容區域動畫 .fade-enter { opacity: 0; } .fade-leave { opacity: 1; } .fade-enter-active { transition: opacity .5s; } .fade-leave-active { opacity: 0; transition: opacity 0s; } //底部導航欄消失時一般為立馬消失
// 前進:右邊頁面進入的同時,同時左邊頁面在消失 .slide-left-enter { //開始過渡的開始狀態為沿X軸向右平移100%,開始過渡結束時向左平移到原位 transform: translate3d(100%, 0, 0); } .slide-left-leave-active { transform: translate3d(-100%, 0, 0); } .slide-left-enter-active, .slide-left-leave-active { will-change: transform; transition: all .5s; position: absolute; // 解決:頁面切換時空白閃屏的問題 }
// 后退:左邊頁面進入的同時,同時右邊頁面在消失 .slide-right-enter { transform: translate3d(-100%, 0, 0); } .slide-right-leave-active { transform: translate3d(100%, 0, 0); } .slide-left-enter-active, .slide-left-leave-active { will-change: transform; transition: all .5s; position: absolute; // 解決:頁面切換時空白閃屏的問題 }
這樣,在 App.vue 全局注冊了之后,后面的路由就可以自動應用這些過渡效果了。
好了,今天的文章就介紹到這里,如果有不正確的地方,歡迎大家留言指正。
