当前位置:   article > 正文

uniapp 小程序根据权限动态生成 tabbar_uni-simple-router动态路由tabbar

uni-simple-router动态路由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>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103

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
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62

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;


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

6.在 App.vue 中添加操作

	onShow() {
		// 隐藏原生tabbar
		uni.hideTabBar({});
	},
  • 1
  • 2
  • 3
  • 4

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"
			}
		]
	},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

此方法也是通过网上资料查找和我项目自身的情况改造的,如有错误,欢迎各位指出!

最后,记得 pages.json 里面的 tabBar 数据不能超5个,如果一定会超5个,就需要完全自定义,跳转的页面是 tabbar 页面,就只能使用 uni.reLaunch() 方法,并且不需要再 pages.json 里面的 tabBar 配置路径!!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/89819
推荐阅读