小程序开发实战案例之三 | 小程序底部导航栏如何设置
小程序中最常见的功能就是底部导航栏了,今天就来看一下怎么设置一个好看的导航栏~这里我们使用的是支付宝官方小程序 IDE 做示范。

官方提供的底部导航栏
第一步:页面创建
一般的小程序会有四个 tab,我们这次也是配置四个 tab 的导航栏。
首先,我们先创建四个页面:

tab 最多可以设置五个,参考 👉 [tabBar 能设置几个 tab]
第二步:在 app.json 中配置底部导航栏的信息
📌 底部导航栏需要在 app.json 文件中通过 tabBar 属性配置,其中:
- textColor:设置文字颜色
 - selectedColor:设置选中文字颜色
 - backgroundColor:设置背景色
 - items:每个 tab 配置 
- pagePath:对应 tab 页面路径
 - name:对应显示 tab 名称
 - icon:非选中状态下图标路径
 - activeIcon:选中状态下图图标路径
 
 
app.json文件代码
{"pages": ["pages/index/index","pages/mine/mine","pages/sort/sort","pages/basket/basket"],"window": {"defaultTitle": "购物商城"},//底部导航栏的信息"tabBar": {"textColor": "#dddddd","selectedColor": "#49a9ee","backgroundColor": "#ffffff","items": [{"pagePath": "pages/index/index","name": "首页"},{"pagePath": "pages/sort/sort","name": "分类"},{"pagePath": "pages/basket/basket","name": "购物车"},{"pagePath": "pages/mine/mine","name": "我的"}]}
} 
实现效果

这里收集了一下导航栏的常见问题,帮大家避坑:
- [tabBar 的位置是否支持设置成顶部]
 - [切换 tabBar 时报错 Cannot read property 'getCurrentPages' of undefined 如何处理]
 - [如何监听 tabBar 点击事件]
 
第三步:美化导航栏
简单的 tab 功能实现后,我们可以通过图标(icon/activeIcon)、颜色等属性对导航栏进行下美化。
先配一个图标,图标大家可以自行搜索,记得找透明底色图片(否则会有白底儿 😅)。
一个 tab 需要配置图标的两个状态,即 选中状态 和 非选中状态,例如:

创建 images 文件夹,把图片拖进去:

稍微美化后的 tabBar 代码:
 "tabBar": {"textColor": "#0e932e","selectedColor": "#49a9ee","backgroundColor": "#ffffff","items": [{"pagePath": "pages/index/index","icon": "images/index.png","activeIcon": "images/index_t.png","name": "首页"},{"pagePath": "pages/sort/sort","icon": "images/sort.png","activeIcon": "images/sort_t.png","name": "分类"},{"pagePath": "pages/basket/basket","icon": "images/basket.png","activeIcon": "images/basket_t.png","name": "购物车"},{"pagePath": "pages/mine/mine","icon": "images/mine.png","activeIcon": "images/mine_t.png","name": "我的"}]} 
实现效果

配置完上面信息之后一个简单的 tab 页面就出来了,基本就可以满足一般小程序的要求了。
tabBar 样式配置的常见问题给大家参考下:
- [tabBar 的 icon 支持哪些图片格式]
 - [tabBar 的图标推荐大小]
 - [tabbar 是否支持设置字体大小]
 
第四步:导航栏进阶功能
如果对应的页面需要提示用户进行交互的话,我们就可以用到下面的功能,例如 tab 红点提示、tab 文本提示 。
tab 红点提示
通过 my.showTabBarRedDot 方法给【我的】增加红点提醒
//index.js
Page({onLoad(query) {my.showTabBarRedDot({index: 3,//左边开始,从0计数success: function(res) {console.log(res);    //{ "success": true}},fail: function(err) {console.log(err);}})console.info(`Page onLoad with query: ${JSON.stringify(query)}`);},
}) 
实现效果

通过 my.hideTabBarRedDot 方法在点击【我的】时候隐藏红点:
//mine.js
Page({onLoad() {my.hideTabBarRedDot({index: 3,//左边开始,从0计数success: function(res) {console.log(res);   //{ "success": true}},fail: function(err) {console.log(err);}});},
});
 
实现效果

tab 文本提示
通过 my.setTabBarBadge 方法给【购物车】增加数量
<!--index.axml -->
<button size="default" type="primary" onTap="addShop">加入购物车</button> 
//index.js
Page({addShop(){my.setTabBarBadge({index: 2,//左边开始,从0计数text: '8',//全部显示只支持3个字符success(res) {console.log(res);},fail(res) {console.log('setTabBarBadge fail: ', res);}})}
}); 
实现效果

超过 3 个字符效果

如果需要移除文本的话,可以通过 my.removeTabBarBadge 方法实现
//basket.js
Page({onLoad() {my.removeTabBarBadge({index: 2,//左边开始,从0计数success: function(res) {console.log(res);   // { "success": true}},fail: function(err) {console.log(err);}});},
});
 
实现效果

tabBar 切换的问题大家可以参考:
- [小程序 tabBar 页面如何透出消息提示]
 - [tabBar 切换时对应页面的 onShow 会不会触发]
 
自定义底部导航栏
如果想要设置更多能力的 tabBar 的话,可以使用自定义Tab来实现。
⚠ 注意:
- 使用自定义 tabBar 后,与 tabBar 样式相关的接口都无法使用,例如设置红点(my.showTabBarRedDot )、修改样式(my.setTabBarStyle)等。
 - 自定义 tabBar 相当于是自定义了一个组件,可以通过 getTabBar 获取自定义 tabBar 实例进行操作。
 
第一步:创建自定义 tabBar 目录
添加自定义的 tabBar 文件,文件位置和名字要保持一致:

第二步:修改 app.json 文件
配置 app.json 文件,在 tabBar 下添加 customize 属性,设置为 true
{"pages": ["pages/index/index","pages/mine/mine","pages/sort/sort","pages/basket/basket","pages/member/member"],"window": {"defaultTitle": "购物商城"},"tabBar": {"customize": true,"items": [{"pagePath": "pages/index/index","name": "首页"},{"pagePath": "pages/sort/sort","name": "分类"},{"pagePath": "pages/member/member","name": "会员"},{"pagePath": "pages/basket/basket","name": "购物车"},{"pagePath": "pages/mine/mine","name": "我的"}]}
} 
 
第三步:编写自定义 tabBar 代码
customize-tab-bar 文件下
index.axml 页面:
<view class="tabbar_box"><view class="tabbar_nav {{index === 2 ? 'active' : ''}}" onTap="switchTab" data-index="{{index}}" data-item={{item}} a:for="{{tabBar.items}}" a:key="index"><!-- 图标 --><image class="tabbar_icon" src="{{selected === index ? item.activeIcon : item.icon}}"></image><!-- 文字 --><text style="color:{{selected === index ? tabBar.selectedColor : tabBar.textColor}}" >{{item.name}}</text></view>
</view> 
index.js 页面:
Component({data: {selected: 0,tabBar: {textColor: "#0e932e",selectedColor: "#49a9ee",items: [{pagePath: "/pages/index/index",name: "首页",icon: "/images/index.png",activeIcon: "/images/index_t.png",},{pagePath: "/pages/sort/sort",name: "分类",icon: "/images/sort.png",activeIcon: "/images/sort_t.png",},{pagePath: "/pages/member/member",name: "",icon: "/images/member.png",activeIcon: "/images/member_t.png"},{pagePath: "/pages/basket/basket",name: "购物车",icon: "/images/basket.png",activeIcon: "/images/basket_t.png",},{pagePath: "/pages/mine/mine",name: "我的",icon: "/images/mine.png",activeIcon: "/images/mine_t.png",}]}},methods: {switchTab(e) {const {dataset: { item: { pagePath = '' }} = {}} = e.targetmy.switchTab({url: pagePath})}}
});
 
index.acss 页面
.tabbar_box {display: -webkit-box;display: -ms-flexbox;display: flex;-webkit-box-orient: horizontal;-webkit-box-direction: normal;-ms-flex-direction: row;flex-direction: row;-ms-flex-pack: distribute;justify-content: space-around;position: fixed;bottom: 0;left: 0;z-index: 999;width: 100%;box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.2);background: #ffffff;padding-top: 16rpx;padding-bottom: env(safe-area-inset-bottom);box-sizing: content-box;
}.tabbar_nav {display: -webkit-box;display: -ms-flexbox;display: flex;-webkit-box-orient: vertical;-webkit-box-direction: normal;-ms-flex-direction: column;flex-direction: column;-webkit-box-pack: center;-ms-flex-pack: center;justify-content: space-around;-webkit-box-align: center;-ms-flex-align: center;align-items: center;font-size: 25rpx;height: 100%;flex: 1;background: #fff;
}.tabbar_nav.active {padding-top: 50rpx;
}.tabbar_nav.active image {width: 100rpx;z-index: 2;height: 100rpx;border-radius: 50%;line-height: 100rpx;font-size: 50rpx;top: -50rpx;left: 0;right: 0;margin: auto;padding: 0;position: absolute;
}.tabbar_nav.active::after {content: "";position: absolute;width: 120rpx;height: 120rpx;top: -60rpx;left: 0;right: 0;margin: auto;box-shadow: 0 -3rpx 8rpx rgba(0, 0, 0, 0.06);border-radius: 60rpx;background-color: inherit;z-index: 0;
}.tabbar_nav.active::before {content: "";position: absolute;width: 120rpx;height: 30rpx;bottom: 30rpx;left: 0;right: 0;margin: auto;background-color: inherit;z-index: 1;
}.tabbar_icon {width: 40rpx;height: 40rpx;
}.tabbar_nav text {font-size: 24rpx;margin-top: 6rpx;
} 
pages/index 文件下
index.js 文件:
Page({// 页面显示onShow() {if (typeof this.getTabBar === 'function' && this.getTabBar()) {this.getTabBar().setData({selected: 0,});}}
}) 
实现效果

以上就是关于小程序底部导航栏的所有内容啦,希望对你有所帮助*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。
相关文章:
小程序开发实战案例之三 | 小程序底部导航栏如何设置
小程序中最常见的功能就是底部导航栏了,今天就来看一下怎么设置一个好看的导航栏~这里我们使用的是支付宝官方小程序 IDE 做示范。 官方提供的底部导航栏 第一步:页面创建 一般的小程序会有四个 tab,我们这次也是配置四个 tab 的…...
Android : 序列化 JSON简单应用
1. JSON介绍 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和写入,同时也易于机器解析和生成。它基于JavaScript的子集,采用完全独立于语言的文本格式来存储和表示数据。JSON是纯文本&#x…...
Java小案例-RocketMQ的11种消息类型,你知道几种?(普通消息和批量消息)
前言 这篇给大家讲普通消息和批量消息,主要配合代码进行讲解,关于RocketMQ的基础知识已经在上篇给大家讲过需要回顾的点击下面这个链接去看 RocketMQ基础知识 普通消息 普通消息其实就很简单,是Apache RocketMQ中最基础的消息形式&#x…...
前端小技巧: 设计一个简版前端统计 SDK
统计 sdk 如何设计 1 ) 概述 客户端一个sdk ,把数据发送给服务端(第三方统计平台)服务端产生一个统计的报表 2 )需求点 访问量:pv自定义事件:用户的一切行为我们都可以自定义采集性能,错误 3 ) 代码实现 const P…...
DevOps搭建(十一)-Jenkins容器内部使用Docker详解
1、目的 配置的目的是使得Jenkins容器可以直接使用宿主机的Docker,从而可以直接使用Docker命令进行本地打包操作,然后推送到Harbor镜像仓库。 2、修改数据卷 如何在docker中执行宿主机的docker操作,我们管它叫docker in docker。 至于为什么要在docker中操作宿主机的doc…...
用户访问认证
注解 Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) Documented public interface Login { }自定义拦截器 Component public class AuthInterceptor implements HandlerInterceptor {ResourceJwtUtils jwtUtils;Overridepublic boolean preHandle(HttpServ…...
前端知识(七)———HTTPS:保护网络通信安全的关键
当谈到网络通信和数据传输时,安全性是一个至关重要的问题。在互联网上,有许多敏感信息需要通过网络进行传输,例如个人身份信息、银行账户信息和商业机密等。为了保护这些信息不被未经授权的人访问和篡改,HTTPS(超文本传…...
element-ui按钮el-button,点击之后恢复之前的颜色
在开发过程中, 使用el-button 按钮点击之后, 没有恢复到之前的颜色, 还是保持点击之后的颜色,需要解决这个问题, <template><div><el-button size"mini" type"primary" plain click"onClick($event)">按钮</el-button>…...
Excel: Python 如何干掉 VBA 系列 乙
以下内容为本人的学习笔记,如需要转载,请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/k2XtfXS3GUt4r2QhizMOVg 创建工作表格 创建表格 xlwings 就可以协助创建插入了宏的 excel 表格。 先找到一个心满意足的目录,一般我…...
算法笔记—链表、队列和栈
链表、队列和栈 1. 链表1.1 单链表反转1.2 双链表反转1.3 合并两个有序链表1.4 链表相加1.5 划分链表 2. 队列和栈2.1 循环队列2.2 栈实现队列2.3 队列实现栈2.4 最小栈2.2 双端队列 1. 链表 1.1 单链表反转 力扣 反转链表 // 反转单链表public ListNode reverseList(ListNod…...
MySQL中的时间函数整理汇总
1.获取当前时间 -- 获取当前时间 SELECT NOW(); -- 获取当前日期 SELECT CURDATE(); -- 获取当前时分秒 SELECT CURTIME(); 2.获取对应日期对应的年/月/日/月份名/星期数 -- 返回对应日期对应的年/月/日/月份名/星期数 select year(now())as 年,month(now())as 月,day(now())…...
stu06-VSCode里的常用快捷键
Alt Z:文字自动换行。当一行的文字太长时,可以使用。或者查看→自动换行Alt Shift ↓ :快速复制当前行到下一行Alt Shift ↑ :快速复制当前行到上一行Alt B:在默认浏览器中打开当前.html文件Ctrl Enter…...
Bypass open_basedir
讲解 open_basedir是php.ini中的一个配置选项,可用于将用户访问文件的活动范围限制在指定的区域。 假设open_basedir/var/www/html/web1/:/tmp/,那么通过web1访问服务器的用户就无法获取服务器上除了/var/www/html/web1/和/tmp/这两个目录以外的文件。…...
【数据库设计和SQL基础语法】--查询数据--过滤
一、过滤数据 1.1 WHERE子句 基本条件过滤 使用比较运算符 在SQL中,基本条件过滤是通过使用比较运算符来限定检索的数据。以下是一些常用的比较运算符和它们的用法: 运算符说明示例等于 ()用于检索列中与指定值相等的行。示例:SELECT * FROM…...
关于git clone速度极慢的解决方法
!!!!前提条件:得有一个可靠且稳定的梯子,如果没有接下来的就不用看了 前言:我在写这篇文章前,也搜索过很多相关git clone速度很慢的解决方法,但是很多很麻烦,…...
软件设计不是CRUD(8):低耦合模块设计实战——组织机构模块(下)
接上文《软件设计不是CRUD(7):低耦合模块设计实战——组织机构模块(中)》 5、某项目研发团队进行扩展 上文中我们介绍了如何研发一个具有较低耦合强度的组织机构模块(包括模块的SDK和模块的默认本地数据库…...
docker-compose Install gitea
gitea 前言 Gitea 是一个轻量级的 DevOps 平台软件。从开发计划到产品成型的整个软件生命周期,他都能够高效而轻松的帮助团队和开发者。包括 Git 托管、代码审查、团队协作、软件包注册和 CI/CD。它与 GitHub、Bitbucket 和 GitLab 等比较类似。 Gitea 最初是从 Gogs 分支而来…...
【Pytorch】学习记录分享1——Tensor张量初始化与基本操作
1. 基础资料汇总 资料汇总 pytroch中文版本教程 PyTorch入门教程 B站强推!2023公认最通俗易懂的【PyTorch】教程,200集付费课程(附代码)人工智能_机器 视频 1.PyTorch简介 2.PyTorch环境搭建 basic: python numpy pandas pytroch…...
Python数据科学视频讲解:Python的数据运算符
2.9 Python的数据运算符 视频为《Python数据科学应用从入门到精通》张甜 杨维忠 清华大学出版社一书的随书赠送视频讲解2.9节内容。本书已正式出版上市,当当、京东、淘宝等平台热销中,搜索书名即可。内容涵盖数据科学应用的全流程,包括数据科…...
参数学习——糖果问题(人工智能期末复习)
之前看了好久都不知道这题咋写,后来看了这篇机器智能-高频问题:糖果问题,大概看明白了,其实主要围绕着这两个公式 光看公式也看不懂,还是要结合题目来 己知有草莓味和酸橙味两种类型的糖果,分别放入5种不同…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
