微信官方文档对自定义 tabBar 的阐述较为潦草,在开发自定义 tabBar 过程中我踩了很多坑,因此在此处做个总结。官方文档我使用 Vant Weapp 作为 UI 组件库,下面以此组件库为例。Vant Weapp 定义 tabBar
定义 tabBar定义 tabBar
创建自定义 tabBar 文件创建自定义 tabBar 文件创建一个与 /pages 的同级目录,命名为
/custom-tab-bar,注意目录层级与目录命名问题,不可用其他名称命名。
在 /custom-tab-bar 下创建四个文件:
index.js
index.json
index.wxml
index.wxss
index.js
index.json
index.wxml
index.wxssindex.jsindex.js在 index.js 中我们定义相关数据:

active:当前被点击 tab 的索引

list:tab 列表
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,

})
}
}
})

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
}

{
"component": true
}
因为我使用了Vant Weapp 的 tabBar 标签栏,所以还需引入额外组件: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"
}
}

{
"component": true,
"usingComponents": {
"van-tabbar": "@vant/weapp/tabbar/index",
"van-tabbar-item": "@vant/weapp/tabbar-item/index",
"van-icon": "@vant/weapp/icon/index"
}
}
index.wxmlindex.wxml在 index.wxml 中定义组件形态,我在此处使用Vant Weapp 的 tabBar 标签栏,详见代码,不再赘述。Vant Weapp tabBar 标签栏

wx:for="{{list}}"
wx:key="index"
icon="{{item.icon}}"
data-path="{{item.pagePath}}">
{{item.text}}




wx:for="{{list}}"
wx:key="index"
icon="{{item.icon}}"
data-path="{{item.pagePath}}">
{{item.text}}


配置 app.json配置 app.json在 app.json 中配置如下参数:

usingComponents:仅声明即可

tabBar:tabBar 组件的具体配置



custom:设为 true,表示使用自定义组件

list:tab 页列表,在列表中的页面将被设置为 tab 页,自动加载 tabBar




usingComponents:仅声明即可tabBar:tabBar 组件的具体配置



custom:设为 true,表示使用自定义组件

list:tab 页列表,在列表中的页面将被设置为 tab 页,自动加载 tabBar





custom:设为 true,表示使用自定义组件

list:tab 页列表,在列表中的页面将被设置为 tab 页,自动加载 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":""

}

]
}
}

{
"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 选中态实现 tabBar 选中态根据微信官方文档描述,每个 tab 页面 tabBar 的实例是不同的:
每个 tab 页下的自定义 tabBar 组件实例是不同的,可通过自定义组件下的 getTabBar 接口,获取当前页面的自定义 tabBar 组件实例。
每个 tab 页下的自定义 tabBar 组件实例是不同的,可通过自定义组件下的 getTabBar 接口,获取当前页面的自定义 tabBar 组件实例。显而易见,每当切换 tab 页时,我们都需要更新 tabBar 的选中态。关于选中态的实现,官方文档描述如下:
注意:如需实现 tab 选中态,要在当前页面下,通过 getTabBar 接口获取组件实例,并调用 setData 更新选中态。
注意:如需实现 tab 选中态,要在当前页面下,通过 getTabBar 接口获取组件实例,并调用 setData 更新选中态。我们可以在使用到 tabBar 的页面中这样实现:
Page({
onShow: function () {
if (typeof this.getTabBar === 'function' && this.getTabBar()) {

this.getTabBar().setData({

// 当前页面的 tabBar 索引

active: 1

})
}
}
})

Page({
onShow: function () {
if (typeof this.getTabBar === 'function' && this.getTabBar()) {

this.getTabBar().setData({

// 当前页面的 tabBar 索引

active: 1

})
}
}
})
至此,一个自定义 tabBar 的实现已全部完成。踩坑踩坑踩坑getTabBar() 方法缺失getTabBar() 方法缺失在实现 tabBar 选中态时遇到 getTabBar() 方法缺失的问题。在小程序开发工具中跳转到 getTabBar() 方法的定义,我们可以看到:
/**
* 返回当前页面的 custom-tab-bar 的组件实例
*
* 最低基础库版本:[`2.6.2`](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html)
**/
getTabBar(): TrivialInstance

/**
* 返回当前页面的 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"
Component is not found in path "custom-tab-bar/index"该原因是由于 tabBar 组件目录放置错误导致的,需要注意以下几点:

目录需与 /pages 同级

目录名称是 custom-tab-bar

目录下所包含的文件名为 index.后缀

在 app.json 配置中,tabBar 下的 custom 字段需设置为 true
目录需与 /pages 同级目录名称是 custom-tab-bar目录下所包含的文件名为 index.后缀在 app.json 配置中,tabBar 下的 custom 字段需设置为 truegetTabBar() 始终返回 null
getTabBar() 始终返回 null
依旧是目录放置与文件命名问题,处理方法同上。另外,不需要在 app.json 的 usingComponents 引入 tabBar 组件,如果你放置目录与命名正确,小程序会自动引入。参考文档参考文档

小程序官方文档:自定义 tabBar

官方自定义 tabbar 的显示和隐藏

使用自定义 tabbar,在 tab 页中使用 this.getTabBar() 一直返回 null,什么原因?

getTabBar 无法调用 接口相关说明在哪里?
小程序官方文档:自定义 tabBar小程序官方文档:自定义 tabBar官方自定义 tabbar 的显示和隐藏官方自定义 tabbar 的显示和隐藏使用自定义 tabbar,在 tab 页中使用 this.getTabBar() 一直返回 null,什么原因?使用自定义 tabbar,在 tab 页中使用 this.getTabBar() 一直返回 null,什么原因?getTabBar 无法调用 接口相关说明在哪里?getTabBar 无法调用 接口相关说明在哪里?总结总结总结