uniapp 小程序根据权限动态生成 tabbar
引言
开发小程序时,有些项目会遇到需要根据角色权限去动态生成 tabbar 的情况,因此就需要开发者自己来定义 tabbar 组件,tabbar 的数量不超过5个
封装 tabbar 组件
1.在 components 目录下定义组件
<template>
<view class="uni-tabbar">
<view class="uni-tabbar-item" v-for="(item, index) in tabbar" :key="index" @tap="changeTab(item)">
<view class="uni-tabbar-bd">
<view class="uni-tabbar-icon">
<image v-if="item.pagePath == pagePath" class="icon-img" mode="aspectFit" :src="validateHttp(item.selectedIconPath)" />
<image v-else class="icon-img" mode="aspectFit" :src="validateHttp(item.iconPath)" />
</view>
</view>
<view class="uni-tabbar-label" :class="{ active: item.pagePath === pagePath }">{{ item.text }}</view>
</view>
</view>
</template>
<script>
import { mapGetters } from 'vuex';
import { isHttpOrHttps } from '@/utils/replace.js';
export default {
props: {
// 当前页面路径
pagePath: {
type: String,
required: true
},
// tabbar 底部导航栏数据
tabbar: {
type: Array,
required: true
}
},
computed: {
...mapGetters(['tabBarList'])
},
// watch: {
// pagePath: {
// handler(val) {
// // console.log('pagePath监听===val', val);
// },
// immediate: true
// }
// },
methods: {
// 检验拼接url地址
validateHttp(url) {
return isHttpOrHttps(url);
},
changeTab(item) {
this.page = item.pagePath;
uni.switchTab({ url: this.page });
this.$emit('onTabTap');
}
}
};
</script>
<style lang="scss" scoped>
.uni-tabbar {
position: fixed;
bottom: 0;
z-index: 50;
width: 100%;
display: flex;
justify-content: space-around;
padding-bottom: calc(24rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
box-sizing: border-box;
border-top: solid 1rpx #dddddd;
background-color: #fff;
.uni-tabbar-item {
width: 25%;
height: 100rpx;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
}
.uni-tabbar-icon {
height: 64rpx;
}
.icon {
display: inline-block;
}
.uni-tabbar-label {
line-height: 24rpx;
font-size: $font-size-sm;
color: $color;
&.active {
font-weight: 600;
}
}
.icon-img {
width: 64rpx;
height: 64rpx;
}
}
</style>
2. 根据权限定义 tabbar 数据
let BUYER = [
{
text: "推荐",
pagePath: '/pages/common/recommend/index',
iconPath: "wxapp-img/icon/ic_tuijian.png",
selectedIconPath: "wxapp-img/icon/ic_tuijian_n.png",
},
{
text: "关注",
pagePath: '/pages/common/brandFollow/index',
iconPath: "wxapp-img/icon/ic_guanuzhu.png",
selectedIconPath: "wxapp-img/icon/ic_guajnzhu_n.png",
},
{
text: "订单",
pagePath: '/pages/buyer/order/index',
iconPath: "wxapp-img/icon/ic_dingdan.png",
selectedIconPath: "wxapp-img/icon/ic_dingdan_n.png",
},
{
text: "我的",
pagePath: '/pages/common/mine/index',
iconPath: "wxapp-img/icon/ic_wode.png",
selectedIconPath: "wxapp-img/icon/ic_wode_n.png",
},
]
let SHOP_MANAGER = [
{
text: "推荐",
pagePath: '/pages/common/recommend/index',
iconPath: "wxapp-img/icon/ic_tuijian.png",
selectedIconPath: "wxapp-img/icon/ic_tuijian_n.png",
},
{
text: "关注",
pagePath: '/pages/common/brandFollow/index',
iconPath: "wxapp-img/icon/ic_guanuzhu.png",
selectedIconPath: "wxapp-img/icon/ic_guajnzhu_n.png",
},
{
text: "采购车",
pagePath: '/pages/manager/car/index',
iconPath: "wxapp-img/icon/ic_caigouche.png",
selectedIconPath: "wxapp-img/icon/ic_caigoouche_n.png",
},
{
text: "我的",
pagePath: '/pages/common/mine/index',
iconPath: "wxapp-img/icon/ic_wode.png",
selectedIconPath: "wxapp-img/icon/ic_wode_n.png",
},
]
export default {
BUYER,
SHOP_MANAGER
}
3.vuex 中获取角色的 tabbar 数据
// modules/tabBar.js
import tabbar from '@/utils/tabbar.js'
const tabBar = {
state: {
role: '',
tabBarList: [],
},
mutations: {
setRole(state, role) {
state.role = role;
state.tabBarList = tabbar[role];
}
},
}
export default tabBar
// getters.js
const getters = {
tabBarList: state => state.tabBar.tabBarList,
role: state => state.tabBar.role
}
export default getters
// index.js
import Vue from 'vue';
import Vuex from 'vuex';
import tabBar from './modules/tabBar.js'
import getters from './getters.js'
Vue.use(Vuex);
const store = new Vuex.Store({
modules: {
tabBar
},
getters
})
export default store;
4.在接口返回角色身份或者权限数据时,设置 vuex 的 tabBarList
5.在需要的页面都引入组件
...
<tab-bar :tabbar="tabBarList" :pagePath="routerPath"/>
...
<script>
import { mapGetters } from 'vuex';
import TabBar from '@/components/TabBar/index.vue';
export default {
data() {
return {
// 获取当前页面路径
routerPath: '/' + this.$mp.page.route,
};
},
computed: {
...mapGetters(['tabBarList'])
},
components: {
TabBar
},
onShow() {
// 隐藏原生tabbar
uni.hideTabBar({});
},
}
</script>
6.在 App.vue 中添加操作
onShow() {
// 隐藏原生tabbar
uni.hideTabBar({});
},
7. pages.json 添加 tabbar 数据
// 根据权限路径去重,把所有的 tabbar 路径添加进去,记得不得超过5个
"tabBar": {
"list": [{
"pagePath": "pages/common/recommend/index"
},
{
"pagePath": "pages/common/brandFollow/index"
},
{
"pagePath": "pages/buyer/order/index"
},
{
"pagePath": "pages/common/mine/index"
},
{
"pagePath": "pages/manager/car/index"
}
]
},
此方法也是通过网上资料查找和我项目自身的情况改造的,如有错误,欢迎各位指出!
最后,记得 pages.json 里面的 tabBar 数据不能超5个,如果一定会超5个,就需要完全自定义,跳转的页面是 tabbar 页面,就只能使用 uni.reLaunch() 方法,并且不需要再 pages.json 里面的 tabBar 配置路径!!!
版权声明:本文为m0_64344940原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。