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

【微信小程序】自定义 tabBar

一、自定义 tabBar

1、案例效果

首先来看一下页面演示效果,页面中有下方标签栏是自定义 tabBar。自定义 tabBar 可以让开发者更加灵活地设置 tabBar 样式,以满足更多个性化的场景。

在这里插入图片描述

在此案例中,用到的主要知识点如下:

  • 自定义组件
  • Vant 组件库
  • MobX 数据共享
  • 组件样式隔离
  • 组件数据监听器
  • 组件的 behaviors
  • Vant 样式覆盖
2、实现步骤

首先来实现 tabBar 标签栏,自定义 tabBar 可分为 3 大步骤,分别是:

  • Step 1、配置信息

app.json 中的 tabBar 项指定 custom 字段,同时其余 tabBar 相关配置也补充完整。所有 tab 页的 json 里需声明 usingComponents 项,也可以在 app.json 全局开启。

app.json

{"tabBar": {"custom": true,"list": [{"pagePath": "pages/home/home","text": "首页","iconPath": "/images/home.png","selectedIconPath": "/images/home-active.png"},{"pagePath": "pages/message/message","text": "消息","iconPath": "/images/message.png","selectedIconPath": "/images/message-active.png"},{"pagePath": "pages/contact/contact","text": "联系我们","iconPath": "/images/contact.png","selectedIconPath": "/images/contact-active.png"}]},
}

注意:当配置自定义 tarBar 页面时,list 属性不能删除,为了保证低版本兼容以及区分哪些页面是 tab 页,tabBar 的相关配置项需完整声明,但这些字段不会作用于自定义 tabBar 的渲染。
注意:此处path不写最前面的 /

  • Step 2、添加 tabBar 代码文件

在代码根目录下添加入口文件,这里的文件夹名一定是 custom-tab-bar,然后在创建 index 组件(index命名也不能随便改,就用 index,否则无法识别)
  当 custom 参数为 true 时,小程序就会自动识别 custom-tab-bar 里面的文件,并将其渲染出来。

在这里插入图片描述

  • Step 3、编写 tabBar 代码

用自定义组件的方式编写即可,该自定义组件完全接管 tabBar 的渲染。另外,自定义组件新增 getTabBar 接口,可获取当前页面下的自定义 tabBar 组件实例。这里使用 Vant Weapp 底部导航栏,用于在不同页面之间进行切换。

1、引入

app.jsonindex.json 中引入组件,这里对组件进行全局引用,具体代码如下所示:

app.json

{"usingComponents":{"my-test1": "/components/test1/test1","my-test2": "/components/test2/test2","my-test3": "/components/test3/test3","my-test4": "/components/test4/test4","my-test5": "/components/test5/test5","van-button": "@vant/weapp/button/index","my-numbers": "./components/numbers/numbers","van-tabbar": "@vant/weapp/tabbar/index","van-tabbar-item": "@vant/weapp/tabbar-item/index"},
}

2、基础用法

index.wxml

<van-tabbar active="{{ active }}" bind:change="onChange"><van-tabbar-item icon="home-o">标签</van-tabbar-item><van-tabbar-item icon="search">标签</van-tabbar-item><van-tabbar-item icon="friends-o">标签</van-tabbar-item><van-tabbar-item icon="setting-o">标签</van-tabbar-item>
</van-tabbar>

index.js

Component({/*** 组件的初始数据*/data: {active: 0,},/*** 组件的方法列表*/methods: {onChange(event) {// event.detail 的值为当前选中项的索引this.setData({ active: event.detail });},}
})

可以来看一下运行效果:

在这里插入图片描述

3、自定义图标

知道怎么引用 Vant 组件之后,接下来就根据需求来对其进行修改,可以通过 slot 自定义图标,其中 icon slot 代表未选中状态下的图标,icon-active slot 代表选中状态下的图标。来看一下 vant 提供的参数 TabbarItem Slot

名称说明
icon未选中时的图标
icon-active选中时的图标

index.wxml

通过 wx: for 将标签栏渲染到页面上。

<van-tabbar active="{{active}}" bind:change="onChange"><van-tabbar-item wx:for="{{list}}" wx:key="index"><imageslot="icon"src="{{ item.iconPath }}"mode="aspectFit"style="width: 25px; height: 25px;"/><imageslot="icon-active"src="{{ item.selectedIconPath }}"mode="aspectFit"style="width: 25px; height: 25px;"/>{{item.text}}</van-tabbar-item>
</van-tabbar>

index.js

app.json 里的 list 数组放在自定义 tabBar 组件中的 data 数据,然后通过循环渲染到页面上。
  注意此处path必须加前面的/,否则在切换tabbar时,会自动拼接地址,导致传入url有误,系统没有任何效果

Component({/*** 组件的初始数据*/data: {active: 0,"list": [{"pagePath": "/pages/home/home",  //复制过来,记得加 /"text": "首页","iconPath": "/images/home.png","selectedIconPath": "/images/home-active.png"},{"pagePath": "/pages/message/message","text": "消息","iconPath": "/images/message.png","selectedIconPath": "/images/message-active.png"},{"pagePath": "/pages/contact/contact","text": "联系我们","iconPath": "/images/contact.png","selectedIconPath": "/images/contact-active.png"}]},/*** 组件的方法列表*/methods: {onChange(event) {// event.detail 的值为当前选中项的索引this.setData({ active: event.detail });},}
})

此时可以看到已经成功把 list 数组里的图片都渲染出来了,来看一下运行效果:

在这里插入图片描述

详细步骤,可以参考小程序官方给出的 文档 。

3、渲染 tabBar 上的数字徽标
  • 渲染数字徽标

通过 van-tabbar-item 上 info 属性可以对 tabBar 渲染数字,具体代码如下所示:

index.wxml

<van-tabbar active="{{active}}" bind:change="onChange"><van-tabbar-item wx:for="{{list}}" wx:key="index" info="2"><imageslot="icon"src="{{ item.iconPath }}"mode="aspectFit"style="width: 25px; height: 25px;"/><imageslot="icon-active"src="{{ item.selectedIconPath }}"mode="aspectFit"style="width: 25px; height: 25px;"/>{{item.text}}</van-tabbar-item>
</van-tabbar>

可以看当对 tabBar 加上数字徽标时,就溢出 tabBar 页面范围。此时需要美化 tabBar 页面, 通过调试器可以看到,图标与标签名中间有间隔。

在这里插入图片描述

在网页开发中,橘黄色的部分代表 margin 。

在这里插入图片描述

  • 美化样式

从上图可以发现,margin-bottom: var(--tabbar-item-margin-bottom,5px);,其中 var 是css中用来引用变量的,当 --tabbar-item-margin-bottom 不存在的时候,就默认为 5px。所以只要重置其 margin-bottom 的值,数字徽标就不会超出 tabBar 范围。

index.wxss

.van-tabbar-item{--tabbar-item-margin-bottom: 0,
}

注意:在自定义组件中使用 Vant Weapp 组件时,需开启 styleIsolation: ‘shared’ 选项

index.js

Component({options: {styleIsolation: 'shared',},
});

可以来看一下运行效果:

在这里插入图片描述

  • 按需添加数字徽标

在实际开发过程中,并不是所以图标都需要添加数字徽标的,所以不能 info 属性将其写死。这里需要把 store 里面的数据绑定组件中进行使用,然后通过数据监听器将数据变化传到数字图标上,具体代码如下所示:

index.wxml

通过判断是否有 info 属性来显示该数字图标,当 info 属性不存在或者为 0 的时候都不显示。

<van-tabbar active="{{active}}" bind:change="onChange"><van-tabbar-item wx:for="{{list}}" wx:key="index" info="{{item.info ? item.info : ''}}"><imageslot="icon"src="{{ item.iconPath }}"mode="aspectFit"style="width: 25px; height: 25px;"/><imageslot="icon-active"src="{{ item.selectedIconPath }}"mode="aspectFit"style="width: 25px; height: 25px;"/>{{item.text}}</van-tabbar-item>
</van-tabbar>

index.js

在消息图标后添加 info 属性。

// custom-tab-bar/index.js
// 导入
import {storeBindingsBehavior} from 'mobx-miniprogram-bindings'
import {store} from '../store/store'Component({// 挂载behaviors: [storeBindingsBehavior],// 全局数据操作storeBindings: {store,fields:{sum: 'sum'},actions: {}},// 数据监听observers:{"sum": function (value){this.setData({"list[1].info": value})}},/*** 组件的初始数据*/data: {active: 0,"list": [{"pagePath": "pages/home/home","text": "首页","iconPath": "/images/home.png","selectedIconPath": "/images/home-active.png"},{"pagePath": "pages/message/message","text": "消息","iconPath": "/images/message.png","selectedIconPath": "/images/message-active.png",info: 2},{"pagePath": "pages/contact/contact","text": "联系夜阑","iconPath": "/images/contact.png","selectedIconPath": "/images/contact-active.png"}]},
})

可以看到对全局数据进行操作时,消息的数字徽标也会随着变化,运行效果如下所示:

请添加图片描述

4、实现tabBar 页面切换效果

通过监听 tabBarchange 事件,得到当前选中项的索引,根据这个索引找到对应页面路径,最后用 wx.switchTab 进行页面跳转。

store.js

不用在组件data 里面定义选中项的索引,不然会出现问题(坑点),最好定义在 store 中,先在 store 定义变量和修改方法。

export const store = observable({// 需要挂载的数据 -- 数据字段numA: 1,numB: 3,name: "我是夜阑的狗",activeTabBarIndex: 0,// 计算属性 -- get为修饰符get sum(){return this.numA + this.numB;},// actions 函数,专门来修改 store 中数据的值updateNum1: action(function(step){this.numA += step;}),updateNum2: action(function(step){this.numB += step;}),updateName: action(function(name){this.name = name;}),updateActiveTabBarIndex: action(function(index){this.activeTabBarIndex = index;})
})

index.js

将全局数据里的索引变量和修改方法挂载到组件中。

// custom-tab-bar/index.js
// 导入
import {storeBindingsBehavior} from 'mobx-miniprogram-bindings'
import {store} from '../store/store'Component({// 挂载behaviors: [storeBindingsBehavior],// 全局数据操作storeBindings: {store,fields:{sum: 'sum',active: 'activeTabBarIndex'},actions: {updateActive: 'updateActiveTabBarIndex'}},/*** 组件的方法列表*/methods: {onChange(event) {// event.detail 的值为当前选中项的索引// this.setData({ active: event.detail });this.updateActive(event.detail);wx.switchTab({url: this.data.list[event.detail].pagePath,})},}
})

注意:这里页面路径 一定要以斜线根路径开头,否则无法识别。

可以来看一下运行效果:

请添加图片描述

5、修改 tabBar 选中项文本的颜色值

最后就是来修改 tabBar 选中项文本的颜色值,来看一下 Vant 提供 tabBar 参数 Tabbar Props :

参数说明类型默认值
active当前选中标签的索引number-
fixed是否固定在底部booleantrue
placeholder固定在底部时,是否在标签位置 生成一个等高的占位元素booleanfalse
border是否展示外边框booleantrue
z-index元素 z-indexnumber1
active-color选中标签的颜色string#1989fa
inactive-color未选中标签的颜色string#7d7e80
safe-area-inset-bottom是否为 iPhoneX 留出底部安全距离booleantrue

index.wxml

<van-tabbar active="{{active}}" bind:change="onChange" active-color='#13A7A0'><van-tabbar-item wx:for="{{list}}" wx:key="index" info="{{item.info ? item.info : ''}}"><imageslot="icon"src="{{ item.iconPath }}"mode="aspectFit"style="width: 25px; height: 25px;"/><imageslot="icon-active"src="{{ item.selectedIconPath }}"mode="aspectFit"style="width: 25px; height: 25px;"/>{{item.text}}</van-tabbar-item>
</van-tabbar>

可以来看一下运行效果:

在这里插入图片描述


相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 计算机毕设选题推荐-基于python的豆瓣电子图书数据可视化分析
  • Python脚本参数总结:argparse库基础用法
  • docker容器使用aconda运行python程序
  • KVM是什么,如何给一台Linux系统使用KVM技术变成好几个不同配置的Linux系统?
  • 回首“八年级上册语文课本”-----原文+感慨
  • angular xlsx-style,复杂表头样式导出
  • Redis的内存淘汰策略-noeviction
  • [kylin M900]麒麟操作系统固件修改与合成
  • 超级会员卡积分收银系统源码,一站式解决方案,可以收银的小程序 带完整的安装代码包以及搭建部署教程
  • WAF和防火墙有什么区别
  • 基于jstack、jmap、jstat 进行JVM监控
  • 避坑之:深信服AC跨三层取MAC(核心交换机是锐捷S7808C_RGOS 11.0(4)B2P1)
  • Java Operator SDK
  • day01-项目概述、环境搭建
  • CMake构建学习笔记13-opencv库的构建
  • JavaScript 如何正确处理 Unicode 编码问题!
  • [译] React v16.8: 含有Hooks的版本
  • Akka系列(七):Actor持久化之Akka persistence
  • JavaScript实现分页效果
  • Java知识点总结(JavaIO-打印流)
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • SQLServer之创建数据库快照
  • 力扣(LeetCode)56
  • 聊聊directory traversal attack
  • 配置 PM2 实现代码自动发布
  • 数据可视化之 Sankey 桑基图的实现
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • ​香农与信息论三大定律
  • ‌JavaScript 数据类型转换
  • # .NET Framework中使用命名管道进行进程间通信
  • #pragma multi_compile #pragma shader_feature
  • #QT项目实战(天气预报)
  • #VERDI# 关于如何查看FSM状态机的方法
  • #宝哥教你#查看jquery绑定的事件函数
  • $.ajax中的eval及dataType
  • (04)odoo视图操作
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (ISPRS,2021)具有遥感知识图谱的鲁棒深度对齐网络用于零样本和广义零样本遥感图像场景分类
  • (Java入门)学生管理系统
  • (PADS学习)第二章:原理图绘制 第一部分
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (十一)图像的罗伯特梯度锐化
  • (一)Kafka 安全之使用 SASL 进行身份验证 —— JAAS 配置、SASL 配置
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • .cn根服务器被攻击之后
  • .mysql secret在哪_MySQL如何使用索引
  • .NET 4.0中的泛型协变和反变
  • .NET 常见的偏门问题
  • .NET 读取 JSON格式的数据
  • .NET简谈互操作(五:基础知识之Dynamic平台调用)
  • .NET开源项目介绍及资源推荐:数据持久层
  • .sh 的运行
  • /3GB和/USERVA开关
  • @EventListener注解使用说明
  • [20170705]diff比较执行结果的内容.txt