超詳細教程實現(xiàn)Vue底部導航欄TabBar
項目介紹:
需求:要求tabbar中的文字可動態(tài)更改,文字對應的圖片動態(tài)更改動態(tài)增加,文字顏色對應更改,TabBarItem的圖片動態(tài)更改和增加,整個項目靈活化,利用插槽,路由,父子組件的值傳遞,利用$router實現(xiàn)點擊item就會顯示對應的頁面。綜合性極強,項目開發(fā)中遇到類似項目,只需復制其中主要代碼即可搭建項目的大體框架。
項目目錄:
TabBar效果預覽:
TabBar實現(xiàn)思路
一、如果在下方有一個單獨的TabBar組件,如何封裝
- 自定義tabbar組件,在APP中使用。
- 讓TabBar處于底部,并且設置相關的樣式。
二、TabBar中現(xiàn)實的內容由外界決定。
- 定義插槽。
- flex布局評分TabBar。
三、自定義TabBarItem,可以傳入圖片和文字
- 自定義tabbarItem,并且定義兩個插槽:圖片,文字。
- 給兩個插槽外層包裝div,用于設置樣式。
- 填充插槽,實現(xiàn)底部TabBar的效果。
方法可行,動手實現(xiàn),首先介紹一下目錄
項目文件目錄建立
文件目錄介紹
我建立一個views文件夾,里面建立五個文件,五個文件里面包含了五個vue文件,分別對應著導航欄下的每個按鈕。
在assets下建立css和img文件夾,放置tabbar按鈕所需的圖片和基礎類
在component文件夾中建立一個MainTabBar.vue文件和tabbar文件夾,tabbar文件夾里放置MainTabBar的子組件和各種插槽關聯(lián)文件。
router文件夾下的index文件配置路由文件
main.js是項目的入口文件,項目中所有的頁面都會加載main.js,所以main.js,主要有三個作用:
- 實例化VUE
- 放置項目中經(jīng)常會用到的插件和CSS樣式,例如網(wǎng)絡請求axios和vue-resource,圖片懶加載模塊:vue-;azyload
- 存儲全局變量例如基本信息等
各個文件夾中的代碼實現(xiàn)
第一步、文件很多,引用會常常帶來404錯誤,這里開始先建立文件別名,vue建立文件別名詳解
找到resolve對象,在alias中寫入各個文件的別名:
文件起別名代碼
代碼:
resolve: { extensions: ['.js', '.vue', '.json'], alias: { '@': resolve('src'), 'assets': resolve('src/assets'), 'components': resolve('src/components'), 'views': resolve('src/views'), } },
App.vue代碼
App.vue中引用MainTabBar組件和各個tabbaritem對應的文件:
<template> <div id="app"> <router-view></router-view> <main-tab-bar></main-tab-bar> </div> </template> <script type="module"> import MainTabBar from 'components/MainTabBar' export default { name: 'App', components:{ MainTabBar } } </script> <style> @import "assets/css/base"; </style>
MainTabBar.vue代碼
MainTabBar組件代碼:要求組件滿足可修改TabBarItem的個數(shù),顏色,文字,等都是動態(tài)的。需要創(chuàng)建各類插槽。
<template> <div> <tab-bar> <tab-bar-item path="/home" activeColor="purple"> <img slot="item-icon" src="~assets/img/tabbar/shouye.png" alt="" > <img slot="item-icon-active" src="~assets/img/tabbar/shouye.active.png" alt=""> <div slot="item-text">首頁</div> </tab-bar-item> <tab-bar-item path="/category" activeColor="purple"> <img slot="item-icon" src="~assets/img/tabbar/fenlei.png" alt=""> <img slot="item-icon-active" src="~assets/img/tabbar/fenlei.active.png" alt=""> <div slot="item-text">分類</div> </tab-bar-item> <tab-bar-item path="/cart" activeColor="purple"> <img slot="item-icon" src="~assets/img/tabbar/gouwuche.png" alt=""> <img slot="item-icon-active" src="~assets/img/tabbar/gouwuche.active.png" alt=""> <div slot="item-text">購物車</div> </tab-bar-item> <tab-bar-item path="/profile" activeColor="purple"> <img slot="item-icon" src="~assets/img/tabbar/wode.png" alt=""> <img slot="item-icon-active" src="~assets/img/tabbar/wode.active.png" alt=""> <div slot="item-text">我的</div> </tab-bar-item> </tab-bar> </div> </template> <script> import TabBar from 'components/tabbar/TabBar' import TabBarItem from 'components/tabbar/TabBarItem' export default { name:"MainTabBar", components:{ TabBar, TabBarItem } } </script> <style> </style>
TabBar.vue代碼
TabBar.vue文件,改文件為MainTabBar.vue中的子組件:
<template> <div id="tab-bar"> <slot></slot> </div> </template> <script> export default { name:'TabBar' } </script> <style> </style>
TabBarItem.vue代碼
TabBarItem.vue為MainTabBar.vue的子組件
<template> <div class="tab-bar-item" @click="itemClick"> <div v-if="!isActive"> <slot name="item-icon"></slot> </div> <div v-else> <slot name="item-icon-active"></slot> </div> <div :style="activeStyle"><slot name="item-text"></slot></div> </div> </template> <script> export default { name:"TabBarItem", props:{ path:String, activeColor:{ type:String, default:'red' } }, data(){ return { // isActive:true } }, computed:{ isActive(){ //判斷 //return this.$route.path.indexOf(this.path) !== -1 //return this.$route.path === this.path return this.$route.path.indexOf(this.path)?false:true }, activeStyle(){ return this.isActive?{color:this.activeColor}:{} } }, methods:{ itemClick(){ this.$router.replace(this.path) } } } </script> <style> #tab-bar{ display: flex; } #tab-bar{ background-color: #f6f6f6; border-top: 2px #ccc; position: fixed; left: 0; right: 0; bottom: 0; box-shadow:0px -1px 1px rgba(100,100,100,.2) ; } .tab-bar-item{ flex: 1; text-align: center; height: 49px; font-size: 14px; } .tab-bar-item img{ width: 24px; height: 24px; margin-top: 3px; vertical-align: middle; margin-bottom: 3px; } .active{ color: red; } </style>
index.js路由配置代碼
router文件夾下的index文件為路由的配置:
import Vue from 'vue' import VueRouter from 'vue-router'; const Home = () => import('views/home/home') const Category = () => import('views/category/category') const Cart = () => import('views/cart/cart') const Profile = () => import('../views/profile/profile') //1.安裝插件 Vue.use(VueRouter) //2.創(chuàng)建路由對象 const routes = [ { path:'', redirect:'/home' }, { path:'/home', component:Home }, { path:'/category', component:Category }, { path:'/cart', component:Cart }, { path:'/profile', component:Profile } ] const router = new VueRouter({ routes, mode:'history' }) //3.導出router export default router
views中的home代碼,cart代碼,profile代碼,category代碼:
home.vue代碼
<template> <h2>首頁</h2> </template> <script> export default { name:"Home" } </script> <style> </style>
category.vue代碼
<template> <h2>分類</h2> </template> <script> export default { name:"Home" } </script> <style> </style>
profile.vue代碼
<template> <h2>個人</h2> </template> <script> export default { name:"Home" } </script> <style> </style>
cart.vue代碼
<template> <h2>購物車</h2> </template> <script> export default { name:"Home" } </script> <style> </style>
Base.css代碼
CSS文件下的base.css內容:
body{ padding: 0px; margin: 0px; }
img圖片資源
實現(xiàn)完成~
總結:
項目綜合性很大,其中有插槽,路由,子組件父組件的值得傳遞,別名設置的各種知識。
項目動態(tài)內容:tabbar的文字,圖片,顏色都可以動態(tài)改變,下次類似項目直接可以引用這些文件。
主要難點:
一、當點擊到對應的TabBarItem上的時候改變圖片顏色,文字顏色,這里是用當前的活躍路由和傳過來的地址是否對應,如果對應就會變?yōu)閠rue返貨來為false:
computed:{ isActive(){ //判斷 return this.$route.path.indexOf(this.path)?false:true }, activeStyle(){ return this.isActive?{color:this.activeColor}:{} } }, methods:{ itemClick(){ this.$router.replace(this.path) } }
上面的代碼還有其他方法:
return this.$route.path.indexOf(this.path) !== -1 return this.$route.path === this.path
二、父組件傳值問題,父組件傳過來對應的文件路徑,對應的字體顏色,子組件接受并使用:
export default { name:"TabBarItem", props:{ path:String, activeColor:{ type:String, default:'red' } }, data(){ return {} },
項目完成~
到此這篇關于Vue實現(xiàn)TabBar底部導航欄的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
詳解在Vue中如何使用axios跨域訪問數(shù)據(jù)
本篇文章主要介紹了在Vue中如何使用axios跨域訪問數(shù)據(jù),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07element-ui自定義message-box自定義樣式不生效的解決
這篇文章主要介紹了element-ui自定義message-box自定義樣式不生效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09