TabBar实现思路
mian.js
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
render: h => h(App)
})
App.vue
<template>
<div id="app">
<router-view></router-view>
<main-tab-bar/>
</div>
</template>
<script>
import MainTabBar from './components/mainTabbar/MainTabBar'
export default {
name: 'App',
components: {
MainTabBar
}
}
</script>
<style>
@import "./assets/css/base.css";
</style>
router.js
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.创建路由对象
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
Home.vue
cart.vue等文件内容类似。
<template>
<h2>首页</h2>
</template>
<script>
export default {
name: "Home",
};
</script>
<style scoped>
</style>
MainTabBar.vue
<template>
<tab-bar>
<tab-bar-item path="/home" activeColor="hotpink">
<img slot="item-icon" src="~assets/img/tabbar/home.svg" alt />
<img slot="item-icon-active" src="~assets/img/tabbar/home_active.svg" alt />
<div slot="item-text">首页</div>
</tab-bar-item>
<tab-bar-item path="/category" activeColor="hotpink">
<img slot="item-icon" src="../../assets/img/tabbar/category.svg" alt />
<img slot="item-icon-active" src="../../assets/img/tabbar/category_active.svg" alt />
<div slot="item-text">分类</div>
</tab-bar-item>
<tab-bar-item path="/cart" activeColor="hotpink">
<img slot="item-icon" src="../../assets/img/tabbar/shopcart.svg" alt />
<img slot="item-icon-active" src="../../assets/img/tabbar/shopcart_active.svg" alt />
<div slot="item-text">购物车</div>
</tab-bar-item>
<tab-bar-item path="/profile" activeColor="deepPink">
<img slot="item-icon" src="../../assets/img/tabbar/profile.svg" alt />
<img slot="item-icon-active" src="../../assets/img/tabbar/profile_active.svg" alt />
<div slot="item-text">我的</div>
</tab-bar-item>
</tab-bar>
</template>
<script>
import TabBar from "components/tabbar/TabBar";
import TabBarItem from "components/tabbar/TabBarItem";
export default {
name: "MainTabBar",
components: {
TabBar,
TabBarItem,
},
};
</script>
<style scoped>
</style>
TarBar.vue
<template>
<div id="tab-bar">
<slot></slot>
</div>
</template>
<script>
export default {
name: "TabBar",
};
</script>
<style scoped>
#tab-bar {
display: flex;
background-color: #f6f6f6;
position: fixed;
left: 0;
right: 0;
bottom: 0;
box-shadow: 0 -1px 1px rgba(100, 100, 100, 0.2);
}
</style>
TarBarItem.vue
<template>
<!--所有的item都展示同一个图片, 同一个文字-->
<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>
<!-- 注意,样式这些不能直接加给 slot,因为slot会被替换,样式不会生效 -->
<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() {
// /home -> item1(/home) = true
// /home -> item1(/category) = false
// /home -> item1(/cart) = true
// /home -> item1(/profile) = true
return this.$route.path.indexOf(this.path) !== -1;
},
activeStyle() {
return this.isActive ? { color: this.activeColor } : {};
},
},
methods: {
itemClick() {
this.$router.replace(this.path);
},
},
};
</script>
<style scoped>
.tab-bar-item {
flex: 1;
text-align: center;
height: 49px;
font-size: 14px;
}
.tab-bar-item img {
24px;
height: 24px;
margin-top: 3px;
vertical-align: middle;
margin-bottom: 2px;
}
</style>