【微信小程序】自定义 tabBar

news2024/12/30 3:17:53

一、自定义 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">
    <image
      slot="icon"
      src="{{ item.iconPath }}"
      mode="aspectFit"
      style="width: 25px; height: 25px;"
    />
    <image
      slot="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">
    <image
      slot="icon"
      src="{{ item.iconPath }}"
      mode="aspectFit"
      style="width: 25px; height: 25px;"
    />
    <image
      slot="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 : ''}}">
    <image
      slot="icon"
      src="{{ item.iconPath }}"
      mode="aspectFit"
      style="width: 25px; height: 25px;"
    />
    <image
      slot="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 : ''}}">
    <image
      slot="icon"
      src="{{ item.iconPath }}"
      mode="aspectFit"
      style="width: 25px; height: 25px;"
    />
    <image
      slot="icon-active"
      src="{{ item.selectedIconPath }}"
      mode="aspectFit"
      style="width: 25px; height: 25px;"
    />
    {{item.text}}
  </van-tabbar-item>
</van-tabbar>

可以来看一下运行效果:

在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2098278.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring 事务传播和自调用行为

为了方便讲解&#xff0c;这里的A、B、C类都是Spring管理的Bean。 自调用行为 自调用行为示例 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component…

【Python报错已解决】“ModuleNotFoundError: No module named ‘torch_scatter‘”

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 引言&#xff1a;一、问题描述1.1 报错示例&#xff1a;1.2 报错分析&#xff1a;1.3 解决思路&#xff1a; 二、解决…

【golang-入门】环境配置、VSCode开发环境配置

golang介绍基础信息 windows环境配置安装包下载安装环境变量设置检查 VSCode开发配置插件配置在 Visual Studio Code 中安装通义灵码go hello word 参考资料 golang介绍 基础信息 golang官网&#xff1a;https://go.dev/golang学习网&#xff1a;https://studygolang.com/使用…

本地服务器使用Docker搭建Nacos动态服务管理平台并实现远程访问

文章目录 前言1. Docker 运行Nacos2. 本地访问Nacos3. Linux安装Cpolar4. 配置Nacos UI界面公网地址5. 远程访问 Nacos UI界面6. 固定Nacos UI界面公网地址7. 固定地址访问Nacos 前言 本文主要介绍如何本地部署动态服务发现、配置管理和服务管理平台 Nacos &#xff0c;并结合…

WCDMA 辅同步信号S_SCH介绍,MATLAB实现

本期主要介绍一下WCDMA辅同步信号S_SCH实现和映射&#xff0c;从公式生成开始介绍&#xff0c;最后用MATLAB实现&#xff0c;让大家了解对比一下3G时代辅同步信号和前面介绍的4G、5G和2G时代的辅同步信号共同点和不同点&#xff0c;不管在什么时候辅同步信号都要遵循一个码要正…

【3.9】贪心算法-解最低加油次数

一、题目 汽车从起点出发驶向目的地&#xff0c;该目的地位于出发位置东面 target 英里处。 沿途有加油站&#xff0c;用数组 stations 表示。其中 stations[i] [positioni, fueli] 表示第 i 个加油站位于出发位置东面 positioni 英里处&#xff0c;并且有 fueli 升汽油。 假设…

bladeX默认审批流flowable如何设置

下面就是流程图必须得写 ${taskUser} 你要配什么 就给审批流的service传什么

自己动手写CPU_step6.1_算数运算指令

序 接上篇的加减指令&#xff0c;本篇主要实现CLZ、CLO、SLT等指令。 CLZ&#xff1a;从最高位开始数0的个数直到遇到1。 例&#xff1a;0x0000,0001 CLZ指令结果&#xff1a;31 0x8000,ffff CLZ指令结果是0 CLZ&#xff1a;从高位开始数1的个数直到遇到0…

告别繁琐,拥抱FileGee——你的高效生活助手!

前言 科技决不是一种自私自利的享乐。有幸能够致力于科技研究的人&#xff0c;首先应该拿自己的学识为人类服务。——马克思&#xff0c;这句话提醒我们&#xff0c;在数字化时代&#xff0c;高效管理自己的数据与时间同样重要。FileGee&#xff0c;正是在这样的背景下应运而生…

【最大上升子序列和】

题目 前置芝士 1. erase 函数 erase(iterator pos)&#xff1a;删除单个元素&#xff0c;其中 pos 是要删除元素的迭代器。 erase(iterator first, iterator last)&#xff1a;删除从 first 到 last&#xff08;不包括 last&#xff09;之间的所有元素。 2. unique 函数 uniqu…

emmc协议

一、简介 1.1 简介 嵌入式多媒体卡&#xff08;Embedded Multimedia Card, eMMC&#xff09;是由 JEDEC 协会所订立&#xff0c;将 MMC controller 和 NAND Flash 封装到一个芯片中&#xff0c;简化存储器的使用和电路板的设计。 1.2 信号 singledescriptionclkclockdata…

Qt22双缓冲机制

Qt22双缓冲机制 知识点drawwidgetdrawwidget.hdrawwidget.cpp mainwindowmainwindow.hmainwindow.cpp main.cpp运行图 知识点 双缓冲就是在内存区申请一块缓存&#xff1b;然后显卡直接从这块内存读取数据.。 这样就不用鼠标边画&#xff0c;经过IO来读取这个环节&#xff1b;…

2024杭电6

1001.造花&#xff08;简单版&#xff09; 题意&#xff1a; 菊花图&#xff1a;n-1个节点都连接同一节点的树。 给定一棵树&#xff0c;删掉一个节点和连向这个点的所有边&#xff0c;使剩下两个连通块都构成菊花图&#xff0c;问是否可以做到。 题解&#xff1a; 菊花图只有…

算法练习题07:无重复字符的最长子串

我们可以使用 滑动窗口 的方法来解决这个问题。这是一种高效的算法&#xff0c;能在 O(n) 的时间复杂度内完成任务。以下是具体的解题思路&#xff1a; 1. 滑动窗口的概念 滑动窗口的想法是使用两个指针&#xff08;通常称为左指针 i 和右指针 j&#xff09;来表示一个窗口。…

秋招/春招投递公司记录表格

最近在准备秋招&#xff0c;在各个平台投递秋招简历&#xff0c;什么官网&#xff0c;邮箱&#xff0c;boss&#xff0c;应届生各个平台上&#xff0c;投递的平台比较多&#xff0c;比较乱&#xff0c;因此自己想将这些平台投递记录都收集到一个表格上&#xff0c;所以在腾讯文…

基于Java+MySQL实现在线书店订购系统

一、引言 1.1 编写目的 编写详细设计说明书是软件开发过程必不可少的部分&#xff0c;其目的是为了使开发人员在完成概要设计说明书的基础上完成概要设计规定的各项模块的具体实现的设计工作。同时也是开发人员和最终客户进行需求交流的有效手段。 1.2 背景 开发软件系统名…

数据结构——排序上

1.排序的概念及其运用 1.1排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&a…

多目标应用:基于自组织分群的多目标粒子群优化算法(SS-MOPSO)的移动机器人路径规划研究(提供MATLAB代码)

一、机器人路径规划介绍 移动机器人&#xff08;Mobile robot&#xff0c;MR&#xff09;的路径规划是 移动机器人研究的重要分支之&#xff0c;是对其进行控制的基础。根据环境信息的已知程度不同&#xff0c;路径规划分为基于环境信息已知的全局路径规划和基于环境信息未知或…

美国海外仓可以用哪家海外仓系统好?

随着全球贸易的增长&#xff0c;美国已经成为了海外仓储业务的一个重要市场。美国海外仓的数量不断增加&#xff0c;竞争也愈加激烈。为应对这种竞争&#xff0c;并优化仓储和供应链管理&#xff0c;WMS&#xff08;仓库管理系统&#xff09;成为了海外仓的重要工具。 一、WMS…