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

常规tabBar
常规实现底部导航的效果,可以参考官方文档 uniapp添加tabBar官方文档地址: uniapp.dcloud.net.cn/collocation…
下面将下图为示例写部分代码案例: 在pages.json写上tabBar 并在List定义好每个页面与页面展示图标,以及不同选中时图标的效果,就可以实现下面页面展示的样式:

案例代码: 注意导航页的图标和页面都必须在根路径下面,因此不能使用网络地址,或分包下的图片和页面。
"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
梳理业务:
- 去除
pages.json写上tabBar注释相关代码; - 通过
uni.hideTabBar();隐藏uniapp自带的tabBar; - 自定义tabBar组件,实现页面相关逻辑;
- 在相关页面引入该组件;
- 根据在页面的onShow方法,当页面显示通过$ref,调用相关逻辑,判断需要显示的底部tabBar按钮和样式。
下面将以下图为案例写相关逻辑:

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

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() {//隐藏tabbaruni.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>
- 组件封装完毕需要在对应的页面中引入该组件 例如 下面
index.vue -
</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}, } - 在tabBar.vue组件写上相关页面判断,例如不同的角色则显示不同的按钮,或不同样式。
tabBar.vue组件中的methods添加一个init函数: -
init() {//获取用户信息let userinfo = uni.getStorageSync('user');// 获取角色状态,赋值给is_identityif (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();//其他业务},
相关文章:
uni-app 实现自定义底部导航
原博:https://juejin.cn/post/7365533404790341651 在开发微信小程序,通常会使用uniapp自带的tabBar实现底部图标和导航,但现实有少量应用使用uniapp自带的tabBar无法满足需求,这时需要自定义底部tabBar功能。 例如下图的需求&am…...
Vue前端开发:animate.css第三方动画库
在实际的项目开发中,如果自定义元素的动画,不仅效率低下,代码量大,而且还存在浏览器的兼容性问题,因此,可以借助一些优秀的第三动画库来协助完成动画的效果,如animate.css和gsap动画库ÿ…...
Java中的I/O模型——BIO、NIO、AIO
1. BIO(Blocking I/O) 1. 1 BIO(Blocking I/O)模型概述 BIO,即“阻塞I/O”(Blocking I/O),是一种同步阻塞的I/O模式。它的主要特点是,当程序发起I/O请求(比如…...
【软考知识】敏捷开发与统一建模过程(RUP)
敏捷开发模式 概述敏捷开发的主要特点包括:敏捷开发的常见实践包括:敏捷开发的优势:敏捷开发的挑战:敏捷开发的方法论: ScrumScrum 的核心概念Scrum 的执行过程Scrum 的适用场景 极限编程(XP)核…...
Redis常见面试题(二)
Redis性能优化 Redis性能测试 阿里Redis性能优化 使用批量操作减少网络传输 Redis命令执行步骤:1、发送命令;2、命令排队;3、命令执行;4、返回结果。其中 1 与 4 消耗时间 --> Round Trip Time(RTT,…...
业务模块部署
一、部署前端 1.1 window部署 下载业务模块前端包。 (此包为耐威迪公司发布,请联系耐威迪客服或售后获得) 包名为:业务-xxxx-business (注:xxxx为发布版本号) 此文件部署位置为:……...
【LeetCode】【算法】48. 旋转图像
LeetCode 48. 旋转图像 题目描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 思路 思路:再次拜见K神…...
【STM32F1】——9轴姿态模块JY901与串口通信(上)
【STM32F1】——9轴姿态模块JY901与串口通信(上) 一、简介 本篇主要对调试JY901模块的过程进行总结,实现了以下功能。 串口普通收发:使用STM32F103C8T6的USART2实现9轴姿态模块JY901串口数据的读取,并利用USART1发送到串口助手。 串口DMA收发:使用STM32F103C8T6的USART…...
Docker网络概述
1. Docker 网络概述 1.1 网络组件 Docker网络的核心组件包括网络驱动程序、网络、容器以及IP地址管理(IPAM)。这些组件共同工作,为容器提供网络连接和通信能力。 网络驱动程序:Docker支持多种网络驱动程序,每种驱动程…...
Vite与Vue Cli的区别与详解
它们的功能非常相似,都是提供基本项目脚手架和开发服务器的构建工具。 主要区别 Vite在开发环境下基于浏览器原生ES6 Modules提供功能支持,在生产环境下基于Rollup打包; Vue Cli不区分环境,都是基于Webpack。 在生产环境下&…...
深究JS底层原理
一、JS中八种数据类型判断方法 在JavaScript中,数据类型分为两大类:基本(原始)数据类型和引用(对象)数据类型。 基本数据类型(Primitive Data Types) 基本数据类型是表示简单的数…...
数据分析-41-时间序列预测之机器学习方法XGBoost
文章目录 1 时间序列1.1 时间序列特点1.1.1 原始信号1.1.2 趋势1.1.3 季节性和周期性1.1.4 噪声1.2 时间序列预测方法1.2.1 统计方法1.2.2 机器学习方法1.2.3 深度学习方法2 XGBoost2.1 模拟数据2.2 生成滞后特征2.3 切分训练集和测试集2.4 封装专用格式2.5 模型训练和预测3 参…...
json转java对象 1.文件读取为String 2.String转为JSONObject 3.JSONObject转为Class
一.参考王广帅的 服务器起服时的加载 private void readConfigFile(String configDir, Class<?> clazz) throws Exception {String fileName getConfigFileName(clazz);File configFile new File(configDir, fileName);// 读取所有的行,因此,应…...
基于卷积神经网络的农作物病虫害识别系统(pytorch框架,python源码)
更多图像分类、图像识别、目标检测等项目可从主页查看 功能演示: 基于卷积神经网络的农作物病虫害检测(pytorch框架)_哔哩哔哩_bilibili (一)简介 基于卷积神经网络的农作物病虫害识别系统是在pytorch框架下实现的…...
ETLCloud异常问题分析ai功能
在数据处理和集成的过程中,异常问题的发生往往会对业务运营造成显著影响。为了提高ETL(提取、转换、加载)流程的稳定性与效率,ETLCloud推出了智能异常问题分析AI功能。这一创新工具旨在实时监测数据流动中的潜在异常,自…...
【1】 Kafka快速入门-从原理到实践
文章目录 🔍 一、引言📜 二、Kafka 的历史🏗️ 三、Kafka 的核心结构🖥️ (一)Broker📋 (二)Topic📄 (三)Partition📤 (四)Producer📥 (五)Consumer🐒 (六)Zookeeper💡 四、Kafka 的重点概念📨 (一)消息📏 (二)偏移量(Offset)🔄 (…...
go语言中的map类型详解
在Go语言中,map是一种内建的数据结构,提供了键值对(key-value)的存储方式。map通常用于实现快速的查找和关联数组,适合在需要根据键来高效查找值的场景下使用。 基本概念 map是一个无序的集合,它存储了键…...
GBase 8a MPP Cluster V9安装部署
GBase 8a MPP Cluster V9安装部署 安装环境准备 节点角色操作系统地址配置GBASE版本gbase01.gbase.cnGCWARE,COOR,DATACentOS 7.9192.168.20.1422C4GGBase 8a MPP Cluster V9 9.5.3.28.12gbase02.gbase.cnGCWARE,COOR,DATACentOS 7.9192.168.20.1432C4GGBase 8a MPP Cluster …...
静态库、动态库、framework、xcframework、use_frameworks!的作用、关联核心SDK工程和测试(主)工程、设备CPU架构
1.1库的概念 库:程序代码的集合,编译好的二进制文件加上头文件供使用,共享程序代码的一种方式。 1.2库的分类 根据开源情况分为:开源库(能看到具体实现)、闭源库(只公开调用的的接口…...
C++ | Leetcode C++题解之第552题学生出勤记录II
题目: 题解: class Solution { public:static constexpr int MOD 1000000007;vector<vector<long>> pow(vector<vector<long>> mat, int n) {vector<vector<long>> ret {{1, 0, 0, 0, 0, 0}};while (n > 0) {…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...
