当前位置: 首页 > article >正文

uni-app 实现自定义底部导航

原博:https://juejin.cn/post/7365533404790341651

在开发微信小程序,通常会使用uniapp自带的tabBar实现底部图标和导航,但现实有少量应用使用uniapp自带的tabBar无法满足需求,这时需要自定义底部tabBar功能。 例如下图的需求,在中间添加一个加号,例如根据不同登录的角色显示不同的tabBar按钮等,这些功能在无法通过 uniapp自带的tabBar实现所以需要写相关组件逻辑。

image.png

常规tabBar

常规实现底部导航的效果,可以参考官方文档 uniapp添加tabBar官方文档地址: uniapp.dcloud.net.cn/collocation…

下面将下图为示例写部分代码案例: 在pages.json写上tabBar 并在List定义好每个页面与页面展示图标,以及不同选中时图标的效果,就可以实现下面页面展示的样式:

image.png

 案例代码: 注意导航页的图标和页面都必须在根路径下面,因此不能使用网络地址,或分包下的图片和页面。

 "tabBar": {
      "color": "#bababa",
      "selectedColor": "#000000",
      "borderStyle": "black",
      "backgroundColor": "#ffffff",
      "list": [
          {
              "pagePath": "pages/tabbar/index/index",
              "iconPath": "static/images/common/shouye.png",
              "selectedIconPath": "static/images/common/shouye-xz.png",
              "text": "首页"
          },
          {
              "pagePath": "pages/talent/index",
              "iconPath": "static/images/common/task.png",
              "selectedIconPath": "static/images/common/task_d.png",
              "text": "达人任务"
          },
          {
              "pagePath": "pages/tabbar/facilitator/facilitator",
              "iconPath": "static/images/common/facilitator.png",
              "selectedIconPath": "static/images/common/facilitator_d.png",
              "text": "服务商"
          },
          {
              "pagePath": "pages/aiTools/aiTools",
              "iconPath": "static/images/common/aitools.png",
              "selectedIconPath": "static/images/common/aitools_d.png",
              "text": "创作助手"
          },
          {
              "pagePath": "pages/tabbar/info/info",
              "iconPath": "static/images/common/info.png",
              "selectedIconPath": "static/images/common/info_d.png",
              "text": "我的"
          }
      ]
     },

自定义tabBar

梳理业务:

  1. 去除pages.json写上tabBar注释相关代码;
  2. 通过uni.hideTabBar();隐藏uniapp自带的tabBar;
  3. 自定义tabBar组件,实现页面相关逻辑;
  4. 在相关页面引入该组件;
  5. 根据在页面的onShow方法,当页面显示通过$ref,调用相关逻辑,判断需要显示的底部tabBar按钮和样式。

下面将以下图为案例写相关逻辑:

image.png

  1. 去除pages.json写上tabBar注释相关代码,图上写了一个list.pagePath 主要的作用是占位,没别的意义

image.png

2.封装tabBar.vue组件

ps:我在components\tabbar\tabbar.vue路径下封装tabBar.vue组件,其他的小伙伴可以根据自己的页面需求写在对应位置,例如想实现首页点击进入不同的分包和页面展示不同的tabBar,那么可以根据自己的需求进行调整。

 

<template>
	<view class="tabbar">
		<view class="tabbar-item" v-for="(item, index) in list" :key="index" @click="changeTab(index)">

			<template v-if="index != 2">
				<view class="select" v-if="current == index">
					<view>
						<view class="i-t position">
							<image class="img imgactive" mode="widthFix" :src="item.selectedIconPath"
								v-if="current == index">
							</image>
							<image class="img" mode="widthFix" :src="item.iconPath" v-else></image>
							<view class="text active" v-if="current == index">{{ item.text }}</view>
							<view class="text" v-else>{{ item.text }}</view>
						</view>
					</view>
				</view>
				<view v-else>
					<view class="i-t">
						<image class="img" mode="widthFix" :src="item.selectedIconPath" v-if="current == index"></image>
						<image class="img" mode="widthFix" :src="item.iconPath" v-else></image>
						<view class="text active" v-if="current == index">{{ item.text }}</view>
						<view class="text" v-else>{{ item.text }}</view>
					</view>
				</view>
			</template>
			<!-- 下面是为了解决自定义业务需求,如果is_identity = 3则显示中间的加号,不然显示服务商 -->
			<template v-else>
				<view class="i-t" v-if="is_identity == 3" >
					<image class="img" mode="widthFix" :src="urladdTask" style="width: 140rpx;height: 140rpx;position: absolute;top: -50rpx;"></image>
				</view>
				<view class="i-t" v-else>
					<view class="select" v-if="current == index">
						<view>
							<view class="i-t position">
								<image class="img imgactive" mode="widthFix" :src="item.selectedIconPath"
									v-if="current == index">
								</image>
								<image class="img" mode="widthFix" :src="item.iconPath" v-else></image>
								<view class="text active" v-if="current == index">{{ item.text }}</view>
								<view class="text" v-else>{{ item.text }}</view>
							</view>
						</view>
					</view>
					<view v-else>
						<view class="i-t">
							<image class="img" mode="widthFix" :src="item.selectedIconPath" v-if="current == index">
							</image>
							<image class="img" mode="widthFix" :src="item.iconPath" v-else></image>
							<view class="text active" v-if="current == index">{{ item.text }}</view>
							<view class="text" v-else>{{ item.text }}</view>
						</view>
					</view>
				</view>
			</template>






		</view>
	</view>
</template>

<script>
//引入图片资源
import addTask from '../../static/images/common/addTask.png'
export default {
	name: "tabbar",
	props: ['current'],
	data() {
		return {
			urladdTask: addTask,
			is_identity: 0,
                        // TODO: 下面list则是你页面上具体展示的底部按钮,根据你的需求和页面进行调整
			list: [
				{
					"pagePath": "pages/tabbar/index/index",
					"iconPath": "../../static/images/common/shouye.png",
					"selectedIconPath": "../../static/images/common/shouye-xz.png",
					"text": "首页"
				},
				{
					"pagePath": "pages/talent/index",
					"iconPath": "../../static/images/common/task.png",
					"selectedIconPath": "../../static/images/common/task_d.png",
					"text": "达人任务"
				},
				{
					"pagePath": "pages/tabbar/facilitator/facilitator",
					"iconPath": "../../static/images/common/facilitator.png",
					"selectedIconPath": "../../static/images/common/facilitator_d.png",
					"text": "服务商"
				},
				{
					"pagePath": "pages/aiTools/aiTools",
					"iconPath": "../../static/images/common/aitools.png",
					"selectedIconPath": "../../static/images/common/aitools_d.png",
					"text": "创作助手"
				},
				{
					"pagePath": "pages/tabbar/info/info",
					"iconPath": "../../static/images/common/info.png",
					"selectedIconPath": "../../static/images/common/info_d.png",
					"text": "我的"
				}
			]

		}
	},

	created() {
		//隐藏tabbar
		uni.hideTabBar();
	},
	mounted() {
	},
	methods: {
		changeTab(e) {
			uni.switchTab({
				url: '/' + this.list[e].pagePath,
			})
		}
	}


}

</script>

<style>
.tabbar {
	font-size: 1.5vh;
	position: fixed;
	left: 0;
	bottom: 0;
	z-index: 99;
	width: 100%;
	height: 6vh;
	display: grid;
	grid-template-columns: repeat(5, 1fr);
	align-items: center;
	justify-content: space-around;
	background-color: #fff;
	padding: 20rpx 0;
}

.tabbar-item {
	height: 100%;
	display: flex;
	align-items: center;
	justify-content: center;
	position: relative;
}
.img {
	height: 3vh;
	width: 2.5vh;
}
.text {
	text-align: center;
	color: #CACACA;
}
.i-t {
	display: flex;
	flex-direction: column;
	justify-items: center;
	align-items: center;
}
.select {
	position: relative;
}

.text.active {
	color: red;
}
.index0 {
	width: 80rpx;
	height: 80rpx;
}
</style>
  1. 组件封装完毕需要在对应的页面中引入该组件 例如 下面index.vue
  2. </template>
    	</view>
                    //current则表示选中的状态,例如当前是首页则current为0,如果是第三页则current=2
    		<tabbar current="0" ref="mytabbar"></tabbar>
    	</view>
    </template>
    
    <script>
    
    import tabbar from '@/components/tabbar/tabbar.vue';
    export default {
        components: {
            tabbar
        },
    }
    

  3. 在tabBar.vue组件写上相关页面判断,例如不同的角色则显示不同的按钮,或不同样式。 tabBar.vue组件中的methods添加一个init函数:
  4.     init() {
            //获取用户信息
            let userinfo = uni.getStorageSync('user');
            // 获取角色状态,赋值给is_identity
            if (userinfo) {
                this.is_identity = userinfo?.identity;
            }
            //...其他调接口等业务处理
        }
    

    在第三步的index.vue页面中,引入的tabbar组件定义了一个ref="mytabbar",可以通过this.$refs.tabBar.init();的方式来调用tabBar.vue组件中的methods的init函数。 例如在index.vue组件下的onShow方法下,当页面显示时候执行tabBar.vue组件中的methods的init函数

        async onShow() {
                await this.getuserinfo();
                //其他业务
        },
    


http://www.kler.cn/a/386598.html

相关文章:

  • see的本质是什么?
  • Python期末复习 | 列表、元组、字典、集合与字符串 | 代码演示
  • 虎扑APP数据采集:JavaScript与AJAX的结合使用
  • Java中 LinkedList<>,ArrayDeque<>的区别 || Queue和Deque的区别
  • 《TCP/IP网络编程》学习笔记 | Chapter 10:多进程服务器端
  • 使用 VS Code 远程连接时解决 OpenSSL 版本不匹配及权限问题
  • 数据库的使用02:SQLServer的连接字符串、备份、还原、SQL监视相关设置
  • 算法训练(leetcode)二刷第二十天 | 93. 复原 IP 地址、78. 子集、90. 子集 II
  • LeetCode34:在排序数组中查找元素第一个和最后一个位置
  • 创新引领,模块化微电网重塑能源格局
  • 使用开源Embedding模型嵌入高维空间向量
  • 设计模式之——单例模式
  • Golang--网络编程
  • 【专题】2024年全球生物医药交易报告汇总PDF洞察(附原数据表)
  • quartz
  • 【计网不挂科】计算机网络期末考试——【选择题&填空题&判断题&简述题】题库(4)
  • ReactNative中实现图片保存到手机相册
  • 3.PyCharm工具
  • virtualBox部署minikube+istio
  • Java项目实战II基于Java+Spring Boot+MySQL的高校办公室行政事务管理系统(源码+数据库+文档)
  • 速盾:vue的cdn是干嘛的?
  • Rust-AOP编程实战
  • vue2 -- el-form组件动态增减表单项及表单项验证
  • 关于我重生到21世纪学C语言这件事——三子棋游戏!
  • Java打造智能语音陪聊软件?提升用户体验的新路径
  • 【数据集】【YOLO】【目标检测】树木倒塌识别数据集 9957 张,YOLO道路树木断裂识别算法实战训练教程!