直接在vue项目封装成一个组件
在components目录下创建tabbar文件夹,然后创建Tabbar.vue和TabbarItem.vue两个组件
Tabbar.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 -3px 10px rgba(100, 100, 100, .2);
}
</style>
TabbarItem.vue内容为下
<template>
<div class="tab-bar-item" @click="itemClick">
<div v-if="!isActive" slot="item-icon">
<slot name="item-icon"></slot>
</div>
<div v-else slot="item-icon-active">
<slot name="item-icon-active"></slot>
</div>
<div slot="item-text" :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 {};
},
computed: {
isActive() {
return this.$route.path.indexOf(this.path) !== -1;
},
activeStyle() {
return this.isActive ? { color: this.activeColor } : { color: "#969595" };
},
},
methods: {
itemClick() {
this.$router.replace(this.path);
},
},
};
</script>
<style scoped>
.tab-bar-item {
flex: 1;
text-align: center;
height: 82px;
font-size: 14px;
}
.tab-bar-item img {
margin: 0 auto;
margin-top: 4px;
width: 28px;
height: 28px;
/* 去掉图片与文字之间的空隙 */
vertical-align: middle;
margin-bottom: 2px;
}
.tab-bar-item img:active {
transform: scale(1.2);
}
</style>
在components目录下创建MainTabBar.vue组件,内容如下
<template>
<div>
<tab-bar>
<tab-bar-item path="/home" activeColor="#EE9351">
<img slot="item-icon" src="@/assets/tabIcon/home.png" />
<img slot="item-icon-active" src="@/assets/tabIcon/home-active.png" />
<div slot="item-text">首页</div>
</tab-bar-item>
<tab-bar-item path="/message" activeColor="#EE9351">
<van-badge
slot="item-icon"
:content="$store.state.messageNum"
max="99"
v-if="$store.state.messageNum > 0"
>
<img class="badge-inner-img" src="@/assets/tabIcon/message.png" />
</van-badge>
<img
slot="item-icon"
src="@/assets/tabIcon/message.png"
v-if="$store.state.messageNum == 0"
/>
<van-badge
slot="item-icon-active"
:content="$store.state.messageNum"
max="99"
v-if="$store.state.messageNum > 0"
>
<img
class="badge-inner-img"
src="@/assets/tabIcon/message-active.png"
/>
</van-badge>
<img
slot="item-icon-active"
src="@/assets/tabIcon/message-active.png"
v-if="$store.state.messageNum == 0"
/>
<div slot="item-text">消息</div>
</tab-bar-item>
<tab-bar-item path="/myself" activeColor="#EE9351">
<img slot="item-icon" src="@/assets/tabIcon/main.png" />
<img slot="item-icon-active" src="@/assets/tabIcon/main-active.png" />
<div slot="item-text">我的</div>
</tab-bar-item>
</tab-bar>
</div>
</template>
<script>
import { selectUnreadCount } from "@/api/publicApi";
import TabBar from "./tabbar/Tabbar";
import TabBarItem from "./tabbar/TabbarItem";
export default {
name: "MainTabBar",
components: {
TabBar,
TabBarItem,
},
data() {
return {
myTarget: null,
};
},
mounted() {
selectUnreadCount().then((res) => {
this.$store.commit("setData", {
messageNum: res.data,
});
});
this.myTarget = setInterval(() => {
selectUnreadCount().then((res) => {
this.$store.commit("setData", {
messageNum: res.data,
});
});
}, 60 * 1000);
},
methods: {},
beforeDestroy() {
clearInterval(this.myTarget);
},
};
</script>
<style scoped>
.badge-inner-img {
margin: 0 auto;
width: 24px;
height: 24px;
vertical-align: middle;
}
</style>
注意,消息做了消息提醒的红点点,图片换成自己项目中的资源,这样点击自带特效的底部导航栏就做好了。