微信官方文档对自定义 tabBar 的阐述较为潦草,在开发自定义 tabBar 过程中我踩了很多坑,因此在此处做个总结。
我使用 Vant Weapp 作为 UI 组件库,下面以此组件库为例。
定义 tabBar
创建自定义 tabBar 文件
创建一个与 /pages 的同级目录,命名为 /custom-tab-bar,注意目录层级与目录命名问题,不可用其他名称命名。
在 /custom-tab-bar 下创建四个文件:
index.js
index.json
index.wxml
index.wxss
index.js
在 index.js 中我们定义相关数据:
- active:当前被点击 tab 的索引
- list:tab 列表
以及一个切换 tab 时触发的方法:
function onChange(event):标签切换时触发,修改 active 值,点亮被点击的 tab 并进行页面跳转
Component({ data: { // 选中的 tab active: null, // 菜单列表 list: [ { pagePath: '/pages/subscriptions/subscriptions', text: '订阅', name: 'subscriptions', icon: 'bullhorn-o' }, { pagePath: '/pages/profile/profile', text: '我的', name: 'profile', icon: 'user-o' } ] }, methods: { // 标签切换 onChange: function (event) { this.setData({ active: event.detail }) wx.switchTab({ url: this.data.list[event.detail].pagePath, }) } } })
index.json
在 index.json 中,将 component 参数值设为 true,代表这是一个自定义组件:
{ "component": true }
因为我使用了Vant Weapp 的 tabBar 标签栏,所以还需引入额外组件:
{ "component": true, "usingComponents": { "van-tabbar": "@vant/weapp/tabbar/index", "van-tabbar-item": "@vant/weapp/tabbar-item/index", "van-icon": "@vant/weapp/icon/index" } }
index.wxml
在 index.wxml 中定义组件形态,我在此处使用Vant Weapp 的 tabBar 标签栏,详见代码,不再赘述。
<van-tabbar active="{{ active }}" bind:change="onChange"> <van-tabbar-item wx:for="{{list}}" wx:key="index" icon="{{item.icon}}" data-path="{{item.pagePath}}"> {{item.text}} </van-tabbar-item> </van-tabbar>
配置 app.json
在 app.json 中配置如下参数:
- usingComponents:仅声明即可
- tabBar:tabBar 组件的具体配置
- custom:设为 true,表示使用自定义组件
- list:tab 页列表,在列表中的页面将被设置为 tab 页,自动加载 tabBar
{ "usingComponents":{ }, "tabBar":{ "custom":true, "color":"#000000", "selectedColor":"#000000", "backgroundColor":"#000000", "list":[ { "pagePath":"pages/subscriptions/subscriptions", "text":"订阅列表", "iconPath":"", "selectedIconPath":"" }, { "pagePath":"pages/profile/profile", "text":"关于我", "iconPath":"", "selectedIconPath":"" } ] } }
实现 tabBar 选中态
根据微信官方文档描述,每个 tab 页面 tabBar 的实例是不同的:
每个 tab 页下的自定义 tabBar 组件实例是不同的,可通过自定义组件下的 getTabBar 接口,获取当前页面的自定义 tabBar 组件实例。
显而易见,每当切换 tab 页时,我们都需要更新 tabBar 的选中态。关于选中态的实现,官方文档描述如下:
注意:如需实现 tab 选中态,要在当前页面下,通过 getTabBar 接口获取组件实例,并调用 setData 更新选中态。
我们可以在使用到 tabBar 的页面中这样实现:
Page({ onShow: function () { if (typeof this.getTabBar === 'function' && this.getTabBar()) { this.getTabBar().setData({ // 当前页面的 tabBar 索引 active: 1 }) } } })
至此,一个自定义 tabBar 的实现已全部完成。
踩坑
getTabBar() 方法缺失
在实现 tabBar 选中态时遇到 getTabBar() 方法缺失的问题。在小程序开发工具中跳转到 getTabBar() 方法的定义,我们可以看到:
/** * 返回当前页面的 custom-tab-bar 的组件实例 * * 最低基础库版本:[`2.6.2`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html) **/ getTabBar(): TrivialInstance
该方法的最低基础版本库为 2.6.2,我们修改 project.config.json 文件中的 libVersion 字段,升级到指定版本库即可。
升级版本库后 tabBar 组件报错
报错内容如下:
Component is not found in path "custom-tab-bar/index"
该原因是由于 tabBar 组件目录放置错误导致的,需要注意以下几点:
- 目录需与 /pages 同级
- 目录名称是 custom-tab-bar
- 目录下所包含的文件名为 index.后缀
- 在 app.json 配置中,tabBar 下的 custom 字段需设置为 true
getTabBar() 始终返回 null
依旧是目录放置与文件命名问题,处理方法同上。
另外,不需要在 app.json 的 usingComponents 引入 tabBar 组件,如果你放置目录与命名正确,小程序会自动引入。
参考文档
- 小程序官方文档:自定义 tabBar
- 官方自定义 tabbar 的显示和隐藏
- 使用自定义 tabbar,在 tab 页中使用 this.getTabBar() 一直返回 null,什么原因?
- getTabBar 无法调用 接口相关说明在哪里?
总结
更新日志
- 群星.2002-恋爱物语情歌对唱精选2CD(引进版)【滚石】【WAV+CUE】
- 群星《闽南情24K德国HD金碟》2CD[WAV+CUE]
- 周传雄《恋人创世纪》环球唱片[WAV+CUE]
- 关淑怡-《真假情话K2HD》(日本压制)【WAV+CUE】
- 王菲 -《Faye Wong》雨果LPCD45 [WAV+分轨][1G]
- 陈百强《世纪10星·永恒篇》环球[WAV+CUE][1G]
- 陈奕迅《黑·白·灰》台湾版[WAV+CUE][400M]
- 张尕怂.2024-甘肃娃娃【FLAC分轨】
- 张惠妹.2011-A.MEI.ACOUSTIC.BEST.2CD【丰华】【WAV+CUE】
- ZEN.1996-珍惜所有【华纳】【WAV+CUE】
- 群星《环球国语元素》香港首版[WAV+CUE][1G]
- 周慧敏《玉女天后》原音母版1:1直刻[WAV+CUE][1G]
- 谭咏麟《20世纪中华歌坛名人百集珍藏版》[WAV+CUE][1G]
- 炉石传说40轮盘术最新卡组代码在哪找 标准40轮盘术卡组代码分享
- 炉石传说亲王贼怎么玩 2024亲王贼最新卡组代码分享