uniapp底部动态tabbar

738 阅读2分钟

案例git地址:asyncTabbar: uniapp动态tabbar案例

实现思路:

  1. 创建一个js文件用来存放所有的tabbar,不同的数组表示不同的tabbar组合。
  2. 创建一个vue文件用来制作底部tabbar组件。
  3. 使用vuex存储用户的身份信息,根据身份信息切换tabbar组合。

具体步骤:

  1. 新建一个tabbar.js文件,将不同的tabbar组合用不同的数组表示出来。
// 公共页面
export const publicBar = [{
		"pagePath": "/pages/home/index",
		"iconPath": require("@/static/logo.png"),
		"selectedIconPath": require("@/static/logo2.jpg"),
		"text": "首页"
	},
	{
		"pagePath": "/pages/car/index",
		"iconPath": require("@/static/logo.png"),
		"selectedIconPath": require("@/static/logo.png"),
		"text": "购物车"
	}
]

// 自己的页面
export const selfBar = [{
		"pagePath": "/pages/home/index",
		"iconPath": require("@/static/logo.png"),
		"selectedIconPath": require("@/static/logo.png"),
		"text": "首页"
	},
	{
		"pagePath": "/pages/mine/index",
		"iconPath": require("@/static/logo.png"),
		"selectedIconPath": require("@/static/logo.png"),
		"text": "我的"
	},
]

  1. 创建一个vue文件编写底部tabbar组件代码
<template>
	<view class="tabbar-list">
		<view class="tabbar-item" v-for="(item, index) in tabBarList" :key="index" @click="changeActive(item, index)">
			<image class="img" :src="activeIndex === index ? item.selectedIconPath : item.iconPath"></image>
			<view>{{ item.text }}</view>
		</view>
	</view>
</template>

<script>
	import {
		mapState,
		mapMutations
	} from 'vuex'
	export default {
		data() {
			return {}
		},
		computed: {
			...mapState('tabBarModule', ['activeIndex', 'tabBarList']),
		},
		methods: {
			...mapMutations('tabBarModule', ['setUserInfo', 'changeIndex']),
			// 修改点击的tabbar项
			changeActive(item, index) {
				this.changeIndex(index)
				uni.switchTab({
					url: item.pagePath
				})
			},
		},
		mounted() {
			// 模拟登录后获取的用户信息,'public'为公共模块,非'public'为我的模块
			this.setUserInfo('public')
			// this.setUserInfo('mine') 用这个进行切换就能看到不同的底部tabbar
		}
	}
</script>
<style lang="scss" scoped>
	.tabbar-list {
		display: flex;
		position: fixed;
		bottom: 0;
		width: 100%;
		height: 100rpx;
		border: 1px solid #ccc;
		overflow: hidden;

		.tabbar-item {
			flex: 1;
			display: flex;
			flex-direction: column;
			align-items: center;
			justify-content: center;

			.img {
				width: 50rpx;
				height: 50rpx;
			}
		}
	}
</style>
  1. 在根目录创建store文件夹,在store文件夹下创建module文件夹和创建index.js文件,在module文件夹下面创建tabBarModule.js文件

image.png

  1. 在tabBarModule.js文件中编写vuex代码,然后在store文件夹下面的index.js文件中引入tabBarModule.js文件作为一个模块
// 引入两个tabbar组合
import {
	publicBar,
	selfBar
} from '@/utils/tabbar.js'
export default {
	// 开启命名空间
	namespaced: true,
	// 存放基础数据
	state: {
		// 用户信息
		userInfo: uni.getStorageSync('userInfo') || '',
		// 初始化一个空的tabbar组合
		tabBarList: [],
		// 当前选中的tabbar项,控制页面刷新导航高亮位置不变
		activeIndex: uni.getStorageSync('acIndex') || 0, 
	},
	mutations: {
		// 保存用户信息
		setUserInfo(state, token) {
			uni.setStorageSync('userInfo', token)
			state.userInfo = token;
			// 根据用户信息切换tabbar组合
			token !== 'public' ?
				state.tabBarList = selfBar :
				state.tabBarList = publicBar

		},
		// 记录当前选中的tabbar项
		changeIndex(state, index) {
			uni.setStorageSync('acIndex', index)
			state.activeIndex = index
		}
	},
}

  1. 在index.js文件中引入tabBarModule模块,并且在mian.js中引入store
import tabBarModule from '@/store/module/tabBarModule.js'
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
	modules: {
		tabBarModule
	}
})
  1. 在每个页面引入刚才的底部tabbar组件,并且使用uni.hideTabBar() 隐藏默认导航栏

image.png

  1. 附上page.json文件供参考
{
	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
		{
			"path": "pages/home/index",
			"style": {
				"navigationBarTitleText": "home"
			}
		},
		{
			"path": "pages/mine/index",
			"style": {
				"navigationBarTitleText": "mine"
			}
		},
		{
			"path": "pages/car/index",
			"style": {
				"navigationBarTitleText": "car"
			}
		}
	],
	"globalStyle": {
		"navigationBarTextStyle": "black",
		"navigationBarTitleText": "uni-app",
		"navigationBarBackgroundColor": "#F8F8F8",
		"backgroundColor": "#F8F8F8"
	},
	"uniIdRouter": {},
	"tabBar": {
		"list": [
			{
				"pagePath": "pages/home/index"
			},
			{
				"pagePath": "pages/mine/index"
			},
			{
				"pagePath": "pages/car/index"
			}
		]
	}
}

8.示例

image.png image.png