vue 封装 tabbar 组件
TabBar.vue
<template>
<div id="tab-bar">
<!-- slot 插槽 -->
<slot></slot>
</div>
</template>
<script>
export default {};
</script>
<style>
#tab-bar {
display: flex;
background-color: #f6f6f6;
position: fixed;
bottom: 0;
left: 0;
right: 0;
box-shadow: 0 -3px 1px 0 rgba(100, 100, 100, 0.1);
}
</style>
TabBarItem.vue
<template>
<div class="tab-bar-item" @click="itemClick(path)">
<!-- 注意插槽会被切换掉的 也就是说样式会被替换掉 可以给slot再套一个标签-->
<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 :class="{active:isActive}">
<slot name="item-text"></slot>
</div>-->
</div>
</template>
<script>
export default {
props: {
// 希望是字符串类型
path: String,
activeColor: {
type: String,
default: "red",
},
},
data() {
return {
// isActive: true,
};
},
computed: {
isActive() {
// 活跃的路由 如果找到返回 true
// /home -> item1(/home) =true
// /home -> item1(/category) =false
// /home -> item1(/cart) =false
// /home -> item1(/profile) =false
return this.$route.path.indexOf(this.path) !== -1;
},
activeStyle() {
return this.isActive ? { color: this.activeColor } : {};
},
},
methods: {
itemClick(path) {
this.$router.replace(path);
},
},
};
</script>
<style>
.tab-bar-item {
flex: 1;
text-align: center;
height: 49px;
font-size: 14px;
}
.tab-bar-item img {
width: 24px;
height: 24px;
/* 去掉图片间隙 */
/* vertical-align: middle; */
}
/* 活跃的样式 为了方便 封装 */
/* .active {
color: red;
} */
</style>
MainTabBar.vue
<template>
<tab-bar>
<!-- 这里没必要加 : 只是为了传递字符串,不是变量 其中的activeColor是为了让使用者自己修改颜色 -->
<tab-bar-item path="/home" activeColor="deepPink">
<template v-slot:item-icon>
<img src="@assets/img/tabbar/home.svg" alt />
</template>
<template v-slot:item-icon-active>
<img src="@assets/img/tabbar/home_active.svg" alt />
</template>
<template v-slot:item-text>
<div>首页</div>
</template>
</tab-bar-item>
<tab-bar-item path="/category" activeColor="deepPink">
<template v-slot:item-icon>
<img src="@assets/img/tabbar/category.svg" alt />
</template>
<template v-slot:item-icon-active>
<img src="@assets/img/tabbar/category_active.svg" alt />
</template>
<template v-slot:item-text>
<div>分类</div>
</template>
</tab-bar-item>
<tab-bar-item path="/cart" activeColor="deepPink">
<template v-slot:item-icon>
<img src="@assets/img/tabbar/cart.svg" alt />
</template>
<template v-slot:item-icon-active>
<img src="@assets/img/tabbar/cart_active.svg" alt />
</template>
<template v-slot:item-text>
<div>购物车</div>
</template>
</tab-bar-item>
<tab-bar-item path="/profile" activeColor="deepPink">
<template v-slot:item-icon>
<img src="@assets/img/tabbar/profile.svg" alt />
</template>
<template v-slot:item-icon-active>
<img src="@assets/img/tabbar/profile_active.svg" alt />
</template>
<template v-slot:item-text>
<div>我的</div>
</template>
</tab-bar-item>
</tab-bar>
</template>
<script>
import TabBar from "@common/tabbar/TabBar.vue";
import TabBarItem from '@common/tabbar/TabBarItem.vue';
export default {
components: {
TabBar,
TabBarItem,
},
};
</script>
<style>
</style>
App.vue
<template>
<div id="app">
<router-view></router-view>
<main-tab-bar></main-tab-bar>
</div>
</template>
<script>
import MainTabBar from "@content/mainTabbar/MainTabBar.vue";
export default {
name: "App",
components:{
MainTabBar
}
};
</script>
<style>
@import "./assets/css/base.css";
</style>
效果图和解析如下