案例效果;

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

  • 自定义组件
  • Vant组件库
  • Mobx数据共享
  • 组件样式隔离
  • 组件数据监听器
  • 组件的behaviors
  • Vant样式覆盖

实现步骤

自定义tabBar分为3打步骤,分别是:

1.配置信息
2.添加tabBar代码文件
3.编写tabBar代码

更详细的,请查看开发者文档

自定义tabBar配置信息:

1.在 app.json 中的 tabBar 项指定 custom 字段,同时其余 tabBar 相关配置也补充完整。
app.json文件中配置"custom":"true"

  "tabBar": {"custom": true,
}

所有 tab 页的 json 里需声明 usingComponents 项,也可以在 app.json 全局开启。

"tabBar": {"custom": true,"color": "#000000","selectedColor": "#000000","backgroundColor": "#000000","usingComponents": {},"list": [{"pagePath": "pages/index/index","text": "index","iconPath": "/images/index.png","selectedIconPath": "/images/indexSelected.png"}]},

此时自定义数组中的list数据不能删

然后在项目的根目录下创建custom-tab-bar文件夹:

然后在该文件夹右键,新建组件,输入index即可创建组件:

然后就可以看到tabbar区域的内容就是这里刚自定义的组件:

这里tabbar建议使用vant组件,vant官网

使用vant第一步,注册组件,我这里使用的是1.3版本的vant,
在app.json中注册(后面两行是新添加的):

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

然后按照文档cv对应的tabbar代码即可

要注意的是,给的模板代码中,可能有一些初始化数据,或是绑定的方法,这些东西也是要cv过来的

例如我cv的wxml代码:

<view><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>
</view>

下面的active,onChange就是cv过来的

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

根据自己的需求(上面领导的需求)写出想要的效果:

样式:


例如想要在未选中时,显示自定义图标,选中时,显示自定义的图标

那么此时还是看官方文档,

文档曰:
自定义图标
可以通过 slot 自定义图标,其中 icon slot 代表未选中状态下的图标,icon-active slot 代表选中状态下的图标(下面代码是文档示例代码)

<van-tabbar active="{{ active }}" bind:change="onChange"><van-tabbar-item info="3"><imageslot="icon"src="{{ icon.normal }}"mode="aspectFit"style="width: 30px; height: 18px;"/><imageslot="icon-active"src="{{ icon.active }}"mode="aspectFit"style="width: 30px; height: 18px;"/>自定义</van-tabbar-item><van-tabbar-item icon="search">标签</van-tabbar-item><van-tabbar-item icon="setting-o">标签</van-tabbar-item>
</van-tabbar>

所以,这里如果要自定义的话,可以:

<view><van-tabbar active="{{ active }}" bind:change="onChange"><van-tabbar-item info="3"><image slot="icon" src="/images/index.png" mode="aspectFit" style="width: 30px; height: 18px;" /><image slot="icon-active" src="/images/indexSelected.png" mode="aspectFit" style="width: 30px; height: 18px;" />首页</van-tabbar-item><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>
</view>


tabbar区域第一个就是刚刚添加的自定义样式
那么此时就可以将tabBar中的list添加到data中,然后在页面上使用遍历来渲染出对应的tabBar:

js:

// custom-tab-bar/index.js
Component({/*** 组件的属性列表*/properties: {},/*** 组件的初始数据*/data: {active:0,"list": [{"pagePath": "pages/index/index","text": "index","iconPath": "/images/index.png","selectedIconPath": "/images/indexSelected.png"}, {"pagePath": "pages/person/person","text": "person","iconPath": "/images/person.png","selectedIconPath": "/images/personSelected.png"}, {"pagePath": "pages/mynumber/mynumber","text": "numberDemo","iconPath": "/images/number.png","selectedIconPath": "/images/numberSelected.png"}]},/*** 组件的方法列表*/methods: {onChange(event) {// event.detail 的值为当前选中项的索引this.setData({ active: event.detail });},}
})

wxml:

<view><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: 30px; height: 18px;" /><image slot="icon-active" src="{{item.selectedIconPath}}" mode="aspectFit" style="width: 30px; height: 18px;" />{{item.text}}</van-tabbar-item></van-tabbar>
</view>

效果:

这里在wxml中可以直接修改icon尺寸的

如何渲染徽标以及美化徽标的样式:

<van-tabbar-item wx:for="{{list}}" wx:key="index" >标签内添加info="2"即可:

美化:

添加徽标之后,徽标其实是溢出tabBar的,所以此时需要修改icon和底部文字的距离,而这里是需要修改margin-bottom

这里需要使用样式覆盖,将需要的样式类名写在css文件中,在js中开启vant的样式覆盖,否则自定义样式不会生效:

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


这里我修改的样式:

.van-tabbar-item__icon{--tabbar-item-margin-bottom:0;
}

按需为tabBar的item项设置徽标数值

对于有的item需要渲染info,有的则不需要,可以在data节点中定义info,并在渲染时使用三元表达式来判断{{item.info? item.info : ''}}:
wxml:

<view><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: 40px; height: 20px;" /><image slot="icon-active" src="{{item.selectedIconPath}}" mode="aspectFit" style="width: 40px; height: 20px;" />{{item.text}}</van-tabbar-item></van-tabbar>
</view>

js:

// custom-tab-bar/index.js
Component({/*** 组件的初始数据*/data: {active:0,"list": [{"pagePath": "pages/index/index","text": "首页","iconPath": "/images/index.png","selectedIconPath": "/images/indexSelected.png","info":2}, {"pagePath": "pages/person/person","text": "个人","iconPath": "/images/person.png","selectedIconPath": "/images/personSelected.png"}, {"pagePath": "pages/mynumber/mynumber","text": "nums","iconPath": "/images/number.png","selectedIconPath": "/images/numberSelected.png"}]}
})

但是将徽标数字写为固定值显然是不合适的,那么此时就可以引用到store中的数据,
关于tabbar的绑定store数据

tabBarr绑定stroe.js:

1.导入,在tabBar的js文件中导入:

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

2.tabBar的js文件中添加配置:


Component({behaviors:[storeBindingsBehavior],
})

3.定义对象:
下面的storeBindings就是需要配置的对象

Component({behaviors:[storeBindingsBehavior],storeBindings:{store,fields:{sum:'sum'},actions:[]},options:{"styleIsolation": "shared"},/*** 组件的属性列表*/properties: {},/*** 组件的初始数据*/data: {active:0,"list": [{"pagePath": "pages/index/index","text": "首页","iconPath": "/images/index.png","selectedIconPath": "/images/indexSelected.png","info":2}, {"pagePath": "pages/person/person","text": "个人","iconPath": "/images/person.png","selectedIconPath": "/images/personSelected.png"}, {"pagePath": "pages/mynumber/mynumber","text": "nums","iconPath": "/images/number.png","selectedIconPath": "/images/numberSelected.png"}]},/*** 组件的方法列表*/methods: {onChange(event) {// event.detail 的值为当前选中项的索引this.setData({ active: event.detail });},}
})

而这里可以使用数据监听器,来监听sum的变化,变化之后立即更改info的值
storeBindings节点平级添加监听器:

  observers: {'sum': function (val) {// console.log(val);this.setData({'list[1].info': val})}},

这里list[1].info就是对应item的徽标数值

点击之后切换不同的页面;

根据上面的步骤,点击不同的tab是不会切换的
而此时,先要完成切换,监听它的点击方法即可,点击事件中,执行wx.switchTab,切换到对应的page,例如:

// 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 (val) {// console.log(val);this.setData({'list[1].info': val})}},options: {"styleIsolation": "shared"},/*** 组件的属性列表*/properties: {},/*** 组件的初始数据*/data: {active: 0,"list": [{"pagePath": "/pages/index/index","text": "首页","iconPath": "/images/index.png","selectedIconPath": "/images/indexSelected.png","info": 2}, {"pagePath": "/pages/person/person","text": "个人","iconPath": "/images/person.png","selectedIconPath": "/images/personSelected.png"}, {"pagePath": "/pages/mynumber/mynumber","text": "nums","iconPath": "/images/number.png","selectedIconPath": "/images/numberSelected.png"}]},/*** 组件的方法列表*/methods: {onChange(event) {// event.detail 的值为当前选中项的索引this.setData({active: event.detail});wx.switchTab({url: this.data.list[event.detail].pagePath,});},}
})

上面的onChange就是监听事件,里面的event.detail是当前tab的index,通过点击不同的tab,传入不同的index,再通过wx.switchTab切换不同的page

注意:这里的this.data.list[event.detail].pagePath改路径必须以/开头,具体可以参考list中的数组

而此时你点击可能会发现点击时,页面是切换了但是激活的tabBar不对

可以将TabBar的active变量定义在store中:

store.js:

// 在这个js文件中专门用来创建store实例对象
import {action,observable
} from 'mobx-miniprogram'
export const store = observable({// 数据字段:num1: 123,num2: 321,step: 2,sum: 0,activeTabBarIndex: 0,// 计算属性,必须加标识符:get(表示当前值是只读的,不能获取当前值):get sum() {return this.num1 + this.num2},// actions函数,用来修改stroe中的数据updateNum1: action(function (step) {this.num1 += step}),updateNum2: action(function (step) {this.num2 += step}),updateActiveTabBarIndex: action(function (index) {this.activeTabBarIndex = index}),
})

这里定义了activeTabBarIndex作为当前激活的index,并有updateActiveTabBarIndex为index更新

tabBar的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'}},observers: {'sum': function (val) {// console.log(val);this.setData({'list[1].info': val})}},options: {"styleIsolation": "shared"},/*** 组件的属性列表*/properties: {},/*** 组件的初始数据*/data: {"list": [{"pagePath": "/pages/index/index","text": "首页","iconPath": "/images/index.png","selectedIconPath": "/images/indexSelected.png","info": 2}, {"pagePath": "/pages/person/person","text": "个人","iconPath": "/images/person.png","selectedIconPath": "/images/personSelected.png"}, {"pagePath": "/pages/mynumber/mynumber","text": "nums","iconPath": "/images/number.png","selectedIconPath": "/images/numberSelected.png"}]},/*** 组件的方法列表*/methods: {onChange(event) {// event.detail 的值为当前选中项的索引// this.setData({active: event.detail});wx.switchTab({url: this.data.list[event.detail].pagePath,});this.updateActive(event.detail)},}
})

这里引入store中的activeTabBarIndexupdateActiveTabBarIndex,在监听tabBar中item的点击时,更新index

tabBar的wxml:

<view><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: 40px; height: 20px;" /><image slot="icon-active" src="{{item.selectedIconPath}}" mode="aspectFit" style="width: 40px; height: 20px;" />{{item.text}}</van-tabbar-item></van-tabbar>
</view>

更改激活样式的文字颜色:

van-tabbar中修改active-color="#07c160":

<view><van-tabbar active="{{active}}" bind:change="onChange" active-color="#07c160"><van-tabbar-item wx:for="{{list}}" wx:key="index" info="{{item.info? item.info : ''}}"><image slot="icon" src="{{item.iconPath}}" mode="aspectFit" style="width: 40px; height: 20px;" /><image slot="icon-active" src="{{item.selectedIconPath}}" mode="aspectFit" style="width: 40px; height: 20px;" />{{item.text}}</van-tabbar-item></van-tabbar>
</view>

微信小程序_25,自定义tabBar相关推荐

  1. 微信小程序+VantWeapp自定义tabBar,解决 this.gettabbar is not a function。

    简单记录一下,写自定义tabBar时的过程与一些问题: 1 引入VantWeapp时,主要用的命令: npm i @vant-weapp 使用这个命令,非常方便后期引入 vant-tabbar 和 v ...

  2. 微信小程序动态设置tab-bar

    微信小程序动态设置tab-bar(自定义) 配置自定义tab-bar的方法这里省略,可以参考官方文档 动态设置tab-bar 需求:根据权限判断底部tab-bar显示内容 例如普通用户这里不显示赛事t ...

  3. 微信小程序 底部导航---tabBar

    微信小程序 底部导航-tabBar 示例图如下: 在app,json页面pages配置中代码如下: "pages": ["pages/home/home",&q ...

  4. 微信小程序图标不支持html,微信小程序实现自定义加载图标功能

    效果图 实现思路 1.首先通过HTML+CSS实现加载动画的静态效果: 2.根据需求给每个动画设计不同的动画效果. 例如第一个加载图标的静态绘制 1.首先确定动画的盒子宽高: 2.设置盒子中每一个长方 ...

  5. 微信小程序可以加服务器上的字体,微信小程序中自定义字体

    微信小程序支持自定义字体开放出来也有段时间,这边整理下使用自定义字体中,容易忽略的一些问题,和简便的全局自定义方式.如果是同时加载两种字体包,先下载下来的会被后下载下来的字体包给覆盖. 官网接口文档 ...

  6. 微信小程序之自定义模态弹窗(带动画)实例

    代码地址如下: http://www.demodashi.com/demo/13991.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.c ...

  7. 微信小程序之——自定义分享按钮(完整版)

    声明 onShareAppMessage 函数 onShareAppMessage() { return {          title: '弹出分享时显示的分享标题'        desc: ' ...

  8. 【微信小程序】自定义弹窗蒙版输入框效果图完整代码

    [微信小程序]自定义弹窗文本输入框效果图&完整代码 效果图 在输入框中进行内容的输入 点击确认后在姓名一栏进行更新修改 点击返回后姓名一栏不做任何修改 在这个的基础上你可以自定义任何弹窗 wx ...

  9. 微信小程序wepy自定义card控件封装

    微信小程序wepy自定义card控件 在利用wepy开发小程序的过程中,需要使用自定义控件来实现,但是很多时候,若直接在page页面中写对应的控件,下次在另一个页面中,想使用同样的控件又需要重新绑定数 ...

最新文章

  1. Proxmox 使用nfs备份及存储iso
  2. 业界资讯: Air 2.0 beta 版本 发布
  3. 【备份恢复】Oracle 数据备份与恢复微实践
  4. python核心编程-第六章-个人笔记(一)
  5. 无线传输层安全协议WTLS安全机制详解
  6. List的遍历 Java
  7. mysql操作查询结果case when then else end用法举例
  8. 旷视 AI 飞跃 | 研究生联合培养计划
  9. 表达式ya是不合法的c语言标识符,《C语言程序设计》试题3及答案
  10. 未找到导入的项目,请确认 Import 声明中的路径正确
  11. 酸了!华为补贴湖北员工每天最高 2000 元
  12. Dell 电话技术支持工程师答用户问(暴笑)
  13. mvn使用assembly打包所有的moudle为一个tgz文件
  14. 创建一个WPF+EF应用程序
  15. 电子产品EMC不合格,如何整改?
  16. 1.16 隐藏不需要打印的内容 [原创Excel教程]
  17. 数理逻辑习题集(9)
  18. server sql 将出生日期转为年龄_sql server 根据身份证号计算出生日期和年龄的存储过程...
  19. STM32外部中断及串口
  20. C/C++日志库-log4cplus(log4j的C++版本)

热门文章

  1. 关于Oracle的impdp和expdp的使用
  2. 数据的万有引力-帆软数智大会
  3. java cxf session_CXF 获取会话session
  4. 1145: 有问题的里程表(2)C语言
  5. unity 将3D物体显示在UI前面(保姆级 超容易)
  6. NDSS加州交通学校课程线上100%及批准
  7. Zabbix监控Kafka topic积压数据
  8. LTD营销SaaS-小程序方案
  9. LeetCode 279.完全平方数
  10. 【死磕Java并发】----- 死磕 Java 并发精品合集