需求
我这里的需求是需要根据后台配置去进行导航页的增加与减少,而uni官方提供的只有对已配置到page.json中的某一个进行样式的变化,并不支持对总的导航页个数进行动态改变,所以这种情况只能用自定义的tabbar去满足。
思路
自定义tabbar可以分为两个部分,样式部分和路由跳转部分
样式方面,自定义一个组件,然后搭配vuex进行图标切换。
路由跳转方面,我这里用了原生的uni.switchTab进行切换,用官方提供的这个方法好处在于不用再次渲染跳转页面,也不会再次调用onload()方法。
实现
样式
<template>
<view style="position: fixed;bottom: 0px;">
<view class="tabbar_box">
<view class="tabbar_item" v-for="(item,index) in tabList" :key="index" @click="changePage(index)">
<image :src="current == index ? item.selectedIconPath:item.iconPath" class="icon" mode="heightFix" />
<view :class="current != index ? 'text':'text_select'" class="text">{{item.text}}</view>
</view>
</view>
</view>
</template>
<style lang="scss" scoped>
.tabbar_box {
background-color: #ffffff;
display: flex;
align-items: center;
height: 100rpx;
padding: 10rpx 0 30rpx 0;
width: 100vw;
.tabbar_item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.icon {
height: 50rpx;
width: 50rpx;
margin-bottom: 6rpx;
}
.text {
color: black;
font-size: 20rpx;
}
.text_select{
color: red;
font-size: 20rpx;
}
}
}
</style>
图标切换变量current和目前用的导航列表,这里用计算属性去实现,当vuex的current这个变量和判断不同导航列表的布尔变量改变时,样式随之改变
computed:{
current(){
return this.$store.state.current
},
tabList(){
if (this.$store.state.haveCheck) {
return this.tabCheck
} else {
return this.tabNormal
}
}
},
点击不同导航按钮时触发的事件
changePage(index) {
let haveCheck = this.$store.state.haveCheck
this.$store.commit("setCurrent",index)
if (!haveCheck) {
switch (index) {
case 0:
uni.switchTab({
url: '/pages/home/home'
})
break;
case 1:
uni.switchTab({
url: '/pages/mine/mine'
})
break;
}
} else {
switch (index) {
case 0:
uni.switchTab({
url: '/pages/home/home'
})
break;
}
}
}
路由跳转
首先需要在page.json创建你所需要所有导航页路径(原生最多支持五个导航页),然后在app.vue的onLaunch()方法使用uni.hideTabBar()隐藏原生的tabbar,然后点击不同的图标会根据tabbar组件的点击方法中的uni.switchTab()切换路由。
页面使用
引用上述tabbar组件,然后可以直接放在页面底部。注意:由于tabbar组件是绝对定位定上去的,所以使用这个组件需要在页面底部留出相对应的位置,否则会出现页面元素被tabbar组件挡住的情况。
这样就能实现自己需要的tabbar组件样式,又能使用原生的路由切换完成自定义导航栏功能了。