一、搭建思路
1、自定义TabBar组件,位于底部,并设置样式
2、TabBar中显示的内容由外界决定,定义插槽,flex布局平分TabBar
3、自定义TabBarItem组件,设置样式,并定义两个插槽:图片和文字
4、填充插槽,实现底部TabBar效果
5、TabBar-TabBarItem和路由动态结合
TabBarItem颜色动态控制
即a、基本框架–>b、插槽–>c、路由点击切换(图片或文字颜色)–>d、路由跳转,点击哪个跳转到对应页面(使用router-view标签)–>e、动态决定isActive
效果图如下:点击哪个跳转到对应页面
二、代码如下
1、main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
router,
}).$mount('#app')
2、App.vue
<template>
<div id="app">
<router-view></router-view>
<tab-bar>
<tab-bar-item path="/home">
<img slot="item-icon" src="./assets/img/tabbar/home.jpg">
<img slot="item-icon-active" src="./assets/img/tabbar/home_active.jpg">
<div slot="item-text">首页</div>
</tab-bar-item>
<tab-bar-item path="/category">
<img slot="item-icon" src="./assets/img/tabbar/category.jpg">
<img slot="item-icon-active" src="./assets/img/tabbar/category_active.jpg">
<div slot="item-text">分类</div>
</tab-bar-item>
<tab-bar-item path="/shop">
<img slot="item-icon" src="./assets/img/tabbar/shopcar.jpg">
<img slot="item-icon-active" src="./assets/img/tabbar/shopcar_active.jpg">
<div slot="item-text">购物车</div>
</tab-bar-item>
<tab-bar-item path="/profile">
<img slot="item-icon" src="./assets/img/tabbar/profile.jpg">
<img slot="item-icon-active" src="./assets/img/tabbar/profile_active.jpeg">
<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: 'App',
components: {
TabBar,
TabBarItem
}
}
</script>
<style>
@import "./assets/css/base.css";
</style>
3、TabBar.vue
<template>
<div id="tab-bar">
<slot></slot>
</div>
</template>
<script>
export default {
name: "TabBar"
}
</script>
<style scoped>
#tab-bar {
height: 49px;
display: flex; /*水平分布*/
background-color: #f6f6f6;
position: fixed; /*位于底部*/
left: 0;
right: 0;
bottom: 0;
box-shadow: 0 -1px 1px rgba(100,100,100,.2); /*底部与上部分之间的阴影*/
}
</style>
4、TabBarItem.vue
<template>
<div class="tab-bar-item" @click="tabBarItemClick">
<div v-if="!isActive"><slot name="item-icon"></slot></div>
<div v-else><slot name="item-icon-active"></slot></div>
<div :class="{active:isActive}"><slot name="item-text"></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:'blue'
}*/
},
computed:{
isActive(){
return this.$route.path.indexOf(this.path) !== -1
}
// TabBarItem颜色动态控制
/*activeStyle(){
return this.isActive ? {
color:this.activeColor} : {
}
}*/
},
methods:{
tabBarItemClick(){
this.$router.push(this.path)
}
}
}
</script>
<style scoped>
.tab-bar-item {
flex: 1; /*平均分布*/
text-align: center;
font-size: 14px;
padding-top: 3px;
}
.tab-bar-item img {
height: 24px;
width: 24px;
vertical-align: middle; /*取掉照片底部默认3个像素*/
margin-bottom: 2px;
}
.active {
color: blue;
}
</style>
5、路由index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
const Home = () => import('../view/home/Home')
const Category = () => import('../view/category/Category')
const Shop = () => import('../view/shop/Shop')
const Profile= () => import('../view/profile/Profile')
Vue.use(VueRouter)
const routes = [
{
path:'',
redirect:'/home'
},
{
path: '/home',
component:Home
},
{
path: '/category',
component:Category
},
{
path: '/shop',
component:Shop
},
{
path: '/profile',
component:Profile
}
]
const router = new VueRouter({
routes,
mode:'history'
})
export default router