微信小程序自定义tabBar

news2024/11/24 17:07:56

1.app.json中tabBar里设置 "custom":true

设置好后就可使用自定义tabBar。

注意:list中的页面必须保存,且必须和自定义的tabBar页面数据一致

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

2.创建tabBar代码文件

在根目录下创建custom-tab-bar文件夹,并创建名为index的component组件。

注意以下三点,否则自定义tabBar不会生效:

  • 必须是根目录下
  • 且文件夹必须名为custom-tab-bar
  • 文件夹下的component组件名必须为index

3.npm下载vant weapp包,并在app.json中引入以下组件

  "usingComponents": {
    "van-button": "@vant/weapp/button/index",
    "van-tabbar": "@vant/weapp/tabbar/index",
    "van-tabbar-item": "@vant/weapp/tabbar-item/index"
  }

 4.自定义tabBar文件 index.wxml文件中,使用<van-tabBar>生成tabBar结构

image 标签中,slot中icon代表非选中图标,icon-active代表选中图标

<van-tabbar active="{{ active }}" bind:change="onChange"
active-color="#07c160">
  <van-tabbar-item info="{{item.info>0?item.info:''}}" wx:for="{{list}}" wx:key="name">
    <image
      slot="icon"
      src="{{ item.icon.normal }}"
      mode="aspectFit"
      style="width: 30px; height: 18px;"
    />
    <image
      slot="icon-active"
      src="{{ item.icon.active }}"
      mode="aspectFit"
      style="width: 30px; height: 18px;"
    />
    {{item.name}}
  </van-tabbar-item>
</van-tabbar>

5.在index.ts中,创建tabBar页面数据

info表示徽标;pagePath表示tab对象页面路径;icon表示选中和非选中图标存放路径

data: {
    // active: 0,
    // list的pagePath: "/pages/home/home"必须再app.json中有对应数据
    list:[{
      info:3,
      name:"首页",
      pagePath: "/pages/home/home",
      icon: {
        normal: '/images/tabs/home.png',
        active: '/images/tabs/home-active.png',
      },
    },{
      name:"消息",
      pagePath: "/pages/message/message",
      icon: {
        normal: 'https://img.yzcdn.cn/vant/user-inactive.png',
        active: 'https://img.yzcdn.cn/vant/user-active.png',
      },
    },{
      name:"联系我们",
      pagePath: "/pages/contact/contact",
      icon: {
        normal: 'https://img.yzcdn.cn/vant/user-inactive.png',
        active: 'https://img.yzcdn.cn/vant/user-active.png',
      },
    }
  ],
  },

6.渲染徽标

通过info属性控制徽标显示,为 '' 时自动不显示,info="{{item.info>0?item.info:''}}"表示按需加载,此处具体情况需要具体分析

<van-tabbar-item info="{{item.info>0?item.info:''}}" wx:for="{{list}}" wx:key="name">

7.如果徽标显示溢出tabBar容器

在index.scss中设置以下: 将margin-bottom设置为0

.van-tabbar-item{
  // scss中变量使用$开头
  $tabbar-item-margin-bottom: 0
}

注意:index.ts中需要设置以下才会生效

  options:{
    "styleIsolation":"shared"
  },

 

8.使用mobx 将徽标的值设置为 动态可变

测试案例:将numA,numB,sum放在store中,numA或者numB改变时,sum计算属性对应改变,然后将sum值和info做同步。

store.ts:

import { observable, action} from 'mobx-miniprogram'

export const store = observable({
  numA: 1,
  numB: 2,
  active: 0,

  get sum(){
    return this.numA + this.numB;
  },
  updateActive:action(function(this: any, active:number){
    this.active = active;
  }),
  updateNumA: action(function(this: any, step:number){
    this.numA += step;
  }),
  updateNumB: action(function(this: any, step:number){
    this.numB += step;
  })

});

home页面展示对应值和两个改变值按钮,改变后,同步index中的徽标属性info

home.wxml:

<view>
<view>
  {{numA}} + {{numB}}  = {{sum}}
</view>
  <van-button type="primary" bindtap="handleNumA" data-step="1"> numA + 1 </van-button>
  <van-button type="info" bindtap="handleNumA" data-step="-1"> numA - 1 </van-button>
</view>
// pages/home/home.ts
import { createStoreBindings } from 'mobx-miniprogram-bindings'
import { store } from '../../store/store'

Page({

  /**
   * 页面的初始数据
   */
  data: {

  },
  handleNumA(this:any, e: any){
    this.updateNumA(e.target.dataset.step-0);
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(this: any) {
    this.storeBindings = createStoreBindings(this,{
      store,
      fields:['numA','numB','sum'],
      actions:['updateNumA']
    });

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload(this: any) {
    this.storeBindings.destroyStoreBindings();
  },

})

 然后再index.ts中监听sum变化,并同步info值

observers:{
    'sum':function(val){
      this.setData({ 'list[0].info': val });
    }
  },

9.实现tabBar页面可切换

<van-tabBar>标签中设置onChange事件通过e.detail回去当前tabBar索引,并调用wx.switchTab()切换到对应页面

<van-tabbar active="{{ active }}" bind:change="onChange"
active-color="#07c160">
  methods: {
    onChange(this:any,e: any){
      // 切换tab页面
      // 将active保存到store中,否则点中项会错乱
      // this.setData({ active: e.detail });
      this.updateActive(e.detail);
      wx.switchTab( {url: this.data.list[e.detail].pagePath} );
    }
  }
})

 11.选中项索引active直接赋值e.detail会混乱,将索引存到store中

store.ts:

export const store = observable({
...
  active: 0,

...
  updateActive:action(function(this: any, active:number){
    this.active = active;
  }),
})

index.ts中再调用updateActive()方法改变active的值 

  methods: {
    onChange(this:any,e: any){
      // 将active保存到store中,否则点中项会错乱
      // this.setData({ active: e.detail });
      this.updateActive(e.detail);
      wx.switchTab( {url: this.data.list[e.detail].pagePath} );
    }
  }
})

12.改变选中项文字颜色

 <van-tabbar>中设置active-color="#07c160"为想要的颜色即可

13.注意:app.json中list中的页面及路径等必须和自定义tabBar自定义组件中的数据相同

data: {
    // active: 0,
    // list的pagePath: "/pages/home/home"必须再app.json中有对应数据
    list:[{
      info:3,
      name:"首页",
      pagePath: "/pages/home/home",
      icon: {
        normal: '/images/tabs/home.png',
        active: '/images/tabs/home-active.png',
      },
    },{
      name:"消息",
      pagePath: "/pages/message/message",
      icon: {
        normal: 'https://img.yzcdn.cn/vant/user-inactive.png',
        active: 'https://img.yzcdn.cn/vant/user-active.png',
      },
    },{
      name:"联系我们",
      pagePath: "/pages/contact/contact",
      icon: {
        normal: 'https://img.yzcdn.cn/vant/user-inactive.png',
        active: 'https://img.yzcdn.cn/vant/user-active.png',
      },
    }
  ],
  },

14.完整代码

代码结构:

 

app.json

{
  "pages": [
    "pages/home/home",
    "pages/message/message",
    "pages/contact/contact"
  ],
  "subpackages": [{
    "root": "packageA",
    "pages": ["pages/basic/basic","pages/logs/logs"]
  },{
    "root": "packageB",
    "pages": ["pages/test1/test1","pages/test2/test2"],
    "independent": true
  }
],
"preloadRule": {
  "packageA/pages/basic/basic":{
    "network": "wifi",
    "packages": ["packageA"]
  }
},
  "tabBar": {
    "custom": true,
    "list": [{
      "pagePath": "pages/home/home",
      "text": "首页",
      "iconPath": "/images/tabs/home.png",
      "selectedIconPath": "/images/tabs/home-active.png"
    },{
      "pagePath": "pages/message/message",
      "text": "消息",
      "iconPath": "/images/tabs/message.png",
      "selectedIconPath": "/images/tabs/message-active.png"
    },{
      "pagePath": "pages/contact/contact",
      "text": "联系我们",
      "iconPath": "/images/tabs/contact.png",
      "selectedIconPath": "/images/tabs/contact-active.png"
    }]
  },
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "Weixin",
    "navigationBarTextStyle": "black"
  },
  "sitemapLocation": "sitemap.json",
  "usingComponents": {
    "van-button": "@vant/weapp/button/index",
    "store-test": "/components/store-test/store-test",
    "van-tabbar": "@vant/weapp/tabbar/index",
    "van-tabbar-item": "@vant/weapp/tabbar-item/index"
  }
}

store.ts:

import { observable, action} from 'mobx-miniprogram'

export const store = observable({
  numA: 1,
  numB: 2,
  active: 0,

  get sum(){
    return this.numA + this.numB;
  },
  updateActive:action(function(this: any, active:number){
    this.active = active;
  }),
  updateNumA: action(function(this: any, step:number){
    this.numA += step;
  }),
  updateNumB: action(function(this: any, step:number){
    this.numB += step;
  })

});

home.wxml:

<!--pages/home/home.wxml-->
<text>pages/home/home.wxml</text>
<view>
<view>
  {{numA}} + {{numB}}  = {{sum}}
</view>
  <van-button type="primary" bindtap="handleNumA" data-step="1"> numA + 1 </van-button>
  <van-button type="info" bindtap="handleNumA" data-step="-1"> numA - 1 </van-button>
</view>

home.ts:

// pages/home/home.ts
import { createStoreBindings } from 'mobx-miniprogram-bindings'
import { store } from '../../store/store'

Page({

  /**
   * 页面的初始数据
   */
  data: {

  },
  handleNumA(this:any, e: any){
    this.updateNumA(e.target.dataset.step-0);
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(this: any) {
    this.storeBindings = createStoreBindings(this,{
      store,
      fields:['numA','numB','sum'],
      actions:['updateNumA']
    });

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload(this: any) {
    this.storeBindings.destroyStoreBindings();
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

index.wxml:

<van-tabbar active="{{ active }}" bind:change="onChange"
active-color="#07c160">
  <van-tabbar-item info="{{item.info>0?item.info:''}}" wx:for="{{list}}" wx:key="name">
    <image
      slot="icon"
      src="{{ item.icon.normal }}"
      mode="aspectFit"
      style="width: 30px; height: 18px;"
    />
    <image
      slot="icon-active"
      src="{{ item.icon.active }}"
      mode="aspectFit"
      style="width: 30px; height: 18px;"
    />
    {{item.name}}
  </van-tabbar-item>
</van-tabbar>

index.ts:

import { ComponentWithStore } from 'mobx-miniprogram-bindings'
import { store } from '../store/store'

ComponentWithStore({
  options:{
    "styleIsolation":"shared"
  },
  observers:{
    'sum':function(val){
      this.setData({ 'list[0].info': val });
    }
  },
  storeBindings:{
    store,
    // 只需要监听sum所以只引入sum
    fields:['sum','active'],
    actions:['updateActive']
  },
  /**
   * 组件的属性列表
   */
  properties: {

  },

  /**
   * 组件的初始数据
   */
  data: {
    // active: 0,
    // list的pagePath: "/pages/home/home"必须再app.json中有对应数据
    list:[{
      info:3,
      name:"首页",
      pagePath: "/pages/home/home",
      icon: {
        normal: '/images/tabs/home.png',
        active: '/images/tabs/home-active.png',
      },
    },{
      name:"消息",
      pagePath: "/pages/message/message",
      icon: {
        normal: 'https://img.yzcdn.cn/vant/user-inactive.png',
        active: 'https://img.yzcdn.cn/vant/user-active.png',
      },
    },{
      name:"联系我们",
      pagePath: "/pages/contact/contact",
      icon: {
        normal: 'https://img.yzcdn.cn/vant/user-inactive.png',
        active: 'https://img.yzcdn.cn/vant/user-active.png',
      },
    }
  ],
  },

  /**
   * 组件的方法列表
   */
  methods: {
    onChange(this:any,e: any){
      // 切换tab页面
      // 将active保存到store中,否则点中项会错乱
      // this.setData({ active: e.detail });
      this.updateActive(e.detail);
      wx.switchTab( {url: this.data.list[e.detail].pagePath} );
    }
  }
})

index.scss:

/* custom-tab-bar/index.wxss */
.van-tabbar-item{
  // scss中变量使用$开头
  $tabbar-item-margin-bottom: 0
}

15.效果实现 

 

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

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

相关文章

基于springboot篮球论坛系统

开发技术介绍 B/S架构 随着软件系统的不断改进和升级&#xff0c;B/S结构产品更为方便的特征体现地十分明显。对于一个中等偏大的公司来说&#xff0c;如果系统管理员每天要在很多台电脑之间来回查看&#xff0c;不断奔走&#xff0c;那么效率和工作量就会变得很低&#xff0…

【Redis】Redis实现点赞、点赞排行榜

目录 一、点赞 1、思路 2、代码实现 二、点赞排行榜 1、思路 2、代码实现 一、点赞 1、思路 在我们的项目中我们有时候会碰到这样的需求&#xff0c;比如实现一个博客系统&#xff0c;当用户访问到这篇博客时可以进行点赞&#xff0c;那么这个功能如何去实现呢&#xff…

Midjourney|文心一格 Prompt:完整参数列表、风格汇总、文生图词典合集

Midjourney|文心一格 Prompt&#xff1a;完整参数列表、风格汇总、文生图词典合集 1.Midjourney 完整参数列表 参数名称 调用方法使用案例注意事项V5V4V3niji版本在关键词后加空格&#xff0c;然后带上版本参数&#xff1a; --v 或者 —v –version 或者 —versionvibrant cali…

【密码学复习】第八讲 数字签名

数字签名&#xff08;Digital Signature&#xff09;&#xff0c;也称电子签名&#xff0c;是指附加在某一电子文档中的一组特定的符号或代码&#xff0c;它是利用数学方法对该电子文档进行关键信息提取并与用户私有信息进行混合运算而形成的&#xff0c;用于标识签发者的身份以…

SpringBoot学习之集成Swagger3(二十七)

一、Maven配置 注意swagger的版本号是3.0.0版本以上才可以,这里我们就选择3.0.0版本 完整的Maven配置如下(仅供参考): <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaL…

vulnhub渗透测试靶场练习1

靶场介绍 靶场名&#xff1a;Medium_socialnetwork 下载地址&#xff1a;https://www.vulnhub.com/entry/boredhackerblog-social-network,454/ 环境搭建 靶机建议选择VM VirtualBox,我一开始尝试使用VMware时会报错&#xff0c;所以改用VM VirtualBox&#xff0c;攻击机使用…

魔改车钥匙实现远程控车:(前传)在macOS上安装使用Arduino

前言 因为最近有个需求需要硬件支持&#xff0c;原本打算使用 Arduino Nano&#xff0c;后来在 Boot 大佬的建议下&#xff0c;买了某宇宙家的 ESP32C3 核心板&#xff0c;对比 Arduino Nano 价格便宜了一大半&#xff0c;而且自身就集成了 WIFI 和 BLE 模块&#xff0c;还不用…

(一)before initialization of D3D(初始化D3D之前你需要了解的D3D基础知识)

什么是D3D? D3D全称Direct X 3D,即一组API可以用来针对GPU编程,不过他最主要的作用是用来渲染(不过现在也有很多其他应用比如d3d11va[Direct X 3D 11 Video API]用来进行硬件加速解码) Tips:Direct X 3D主要用来渲染,既然我们说到可以针对GPU编程了,当然不只是渲染的工作可以…

国考省考行测:数量关系,牛吃草问题,比例问题

国考省考行测&#xff1a;数量关系&#xff0c;牛吃草问题 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&#xff0c;而常规国考省考最重要的还是申论和行测&#xff0c;所以大家认真准备吧&#xff0c;我讲一起屡屡申论…

〖Python网络爬虫实战㉘〗- Selenium案例实战(二)

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;目前专栏免费订阅&#xff0c;在转为付费专栏前订阅本专栏的&#xff0c;可以免费订阅付…

图神经网络(处理点云)PPFNet的实现

文章说明&#xff1a; 1)参考资料&#xff1a;PYG官方文档。超链。 2)博主水平不高&#xff0c;如有错误还望批评指正。 3)我在百度网盘上传了这篇文章的jupyter notebook和有关文献。超链。提取码8848。 文章目录 前言文献阅读代码实操历史遗留问题 前言 本篇文章接上一篇文章…

今年的面试难度,我给跪了……

大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;又得准备面试了&#xff0c;不知道从何下手&#xff01; 不论是跳槽涨薪&#xff0c;还是学习提升&#xff01;先给自己定一个小目标&#xff0c;然后再朝着目标去努力就完事儿了&#xff01; 为了帮大家节约时间&a…

【STM32G431RBTx】备战蓝桥杯嵌入式→决赛试题→第七届

文章目录 前言一、题目二、模块初始化三、代码实现interrupt.h:interrupt.h:main.h:main.h: 四、完成效果五、总结 前言 无 一、题目 二、模块初始化 1.LCD这里不用配置&#xff0c;直接使用提供的资源包就行 2.ADC:开启ADCsingle-ended 3.LED:开启PC8-15,PD2输出模式就行了…

手撕代码——同步FIFO

手撕代码——同步FIFO 一、FIFO原理与设计二、完整代码与仿真结果三、仿真结果 一、FIFO原理与设计 查看Xilinx官方FIFO IP核&#xff0c;其主要的信号有时钟信号、写端口信号、读端口信号&#xff0c;其中&#xff0c;写端口信号包括写满信号full、写使能信号wr_en、写数据输入…

[元带你学: eMMC完全解读 7] eMMC 设备与系统概述

依JEDEC eMMC 5.1及经验辛苦整理,付费内容,禁止转载。 所在专栏 《元带你学: eMMC完全解读》 前言 全文3600 字, 全文介绍eMMC 内部系统框架, Bus 总线宽度, 总线Speed Mode, 了解即可。对应Bus 总线重点看 8 Bit 即可, Speed Mode 重点看 HS400。几乎所有的系统都是跑在…

Java并发编程-synchronized

目录 1. synchronized在jdk 1.6中的优化 1.1 锁消除 1.2 锁粗化 1.2 锁升级/锁膨胀 1.2.1 锁升级原理 1.2.2 自适应自旋锁 2. synchronized实现原理 3. synchronized和Lock的对比 1. synchronized在jdk 1.6中的优化 在JDK1.5的时候,Doug Lee推出了ReentrantLock,lock的…

【密码学复习】第九讲 密钥管理(一)

密钥管理简介 • 柯克霍夫斯原则(Kerckhoffs Principle) 即使密码系统的任何细节已为人悉知&#xff0c;只要密钥未泄漏&#xff0c;它也应是安全的(19世纪). 密钥安全&#xff1a;三分技术&#xff0c;七分管理 密钥管理就是在授权各方之间实现密钥关系的建立和维护…

dom4j 读取xml配置文件,根据配置文件利用反射创建对象

pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 …

maven打包命令打出的可执行的jar包和可依赖的jar包的区别

目录 引出问题: 介绍打包插件 下面开始打包: 解压比较这两个jar包的区别: 引出问题: 当我建了一个maven的springboot项目A写了一个工具类,我把A项目打包成jar包去给B项目用,结果 B项目报错找不到这个jar包. 百度后发现原来jar包分为可执行jar包和可被依赖的jar包 介绍打包…

二、医院设置管理

文章目录 一、医院设置管理1、项目开发流程1.1 定义路由模块1.2 定义api模块1.3 定义页面组件脚本1.4 定义页面组件模板1.5 测试数据通信1.6 跨域处理 2、分页查询2.1 定义页面组件脚本2.2 定义页面组件模板2.3 表单查询 3、删除3.1 定义api模块3.2 定义页面组件模板3.3 定义页…