uni-app 自定义 tabbar 不能直接用 tabbar 配置,因官方仅支持静态图标文字,不支持动态颜色、选中态、badge 及自定义组件;启用需在 pages.json 对应页面的 app-plus/mp-weixin 节点下设 "custom": true,h5 不支持,需手动 bottom: 0 匹配原生高度;状态同步须手动管理路由跳转与 currenttab,并通过 watch $route 或 onshow 更新;badge 应存全局 store 或 storage,用事件订阅更新,避免组件内频繁请求。

uni-app 自定义 tabbar 为什么不能直接用 tabBar 配置?
因为 uni-app 官方的 tabBar 配置只支持静态图标和文字,不支持动态修改图标颜色、选中状态、 badge 数字,更无法嵌入自定义组件(比如带动画的按钮、实时消息红点)。一旦你写了 "custom": true,整个底部导航栏就完全交给你自己实现——官方 tabbar 渲染逻辑被绕过,onTabItemTap 生命周期也不会触发。
怎么在 pages.json 里启用自定义 tabbar?
必须在 pages.json 的对应页面配置中显式开启,且只对设置了该配置的页面生效:
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"app-plus": {
"tabBar": {
"custom": true
}
}
}
}
注意三点:
-
custom: true必须写在app-plus或mp-weixin等平台节点下,不能放在顶层tabBar配置里(否则无效) - H5 端不支持自定义 tabbar,需单独处理或降级为普通 view
- 开启后,原生 tabBar 高度会被预留(iOS 下约 49px,Android 约 56px),你的自定义组件要手动 bottom: 0 并设置固定高度匹配
如何让自定义 tabbar 支持页面切换和状态同步?
核心是手动管理路由跳转 + 当前激活项状态。不能依赖 uni.switchTab() 的自动高亮(它对 custom tabbar 无响应),必须自己控制:
- 用
uni.navigateTo()或uni.switchTab()跳转时,同时更新一个响应式变量(如currentTab) - 每个 tab 页面的
onShow中调用uni.getStorageSync('currentTab')或通过事件总线同步状态 - 推荐在根组件(如
App.vue)用watch监听$route变化,自动更新currentTab - 图标选中态用条件 class 控制,例如:
:class="{ 'active': currentTab === 'home' }"
示例片段(在自定义 tabbar 组件中):
<view class="tab-item"><image :src="currentTab === 'home' ? require('@/static/tabbar/home-active.png') : require('@/static/tabbar/home.png')"></image></view>
switchTab 方法内需同时执行 uni.switchTab({ url: '/pages/home/home' }) 和 this.currentTab = 'home'。
动态 badge 和实时数据怎么更新不卡顿?
避免在 tabbar 组件内部直接请求接口或频繁 setData。正确做法是:
- 把 badge 数据存在全局 store(如 Pinia)或
uni.setStorageSync中 - 用
uni.$on('updateBadge')订阅更新事件,由业务页触发(比如消息页拉取完未读数后 emit) - 图标资源尽量提前加载,不要在
v-if中动态require,否则切换时会闪白 - 微信小程序真机上,
image组件 src 切换有缓存 bug,建议用 base64 或雪碧图规避
容易被忽略的一点:自定义 tabbar 是独立组件,生命周期与页面不同步。如果依赖页面 data 初始化 badge,得在 mounted 后主动触发一次同步,而不是等 onShow。











