pages.json中必须为每个使用自定义tabbar的页面显式设置"custom": true,图标路径须为81×81px本地静态资源,跳转须用uni.switchTab,选中态需监听路由变化,底部需适配安全区。

pages.json 里必须设 "custom": true
不加这行,custom-tab-bar/index.vue 根本不会被加载,图标再好看也出不来。它不是可选项,是开关——设了才真正交出底部控制权。注意:只对当前页面生效,所以每个要用自定义 tabbar 的页面(比如首页、消息页、个人页)的 page.json 配置里都要显式写上 "custom": true,不能只在根 pages.json 的 tabBar 节点下配。
图标路径必须是本地相对路径,且尺寸要对得上
微信小程序要求 iconPath 和 selectedIconPath 是项目内静态资源,不能是网络地址或绝对路径;H5 和 App 端虽宽松些,但统一用 /static/tabbar/home.png 这种写法最稳。尺寸建议严格按 81×81px 准备,官方文档明确说“不支持缩放适配”,小了会糊,大了可能裁切。别用 SVG 或字体图标——原生 tabBar 不认,自定义组件里倒是可以用,但那就跟 iconPath 无关了,属于你手写 <image> 或 <van-icon> 的事。
uni.switchTab 跳转才能保持页面栈干净
自定义 tabbar 后,千万别用 uni.navigateTo 或 uni.redirectTo 跳 tab 页,否则页面栈疯狂堆积,点 5 次“首页”就堆出 5 个首页实例,内存扛不住。必须用 uni.switchTab({ url: '/pages/index/index' }),它会自动关闭其他 tab 页面并跳转。同时注意:list 里每个 pagePath 必须和 pages.json 中声明的路径完全一致(包括大小写和斜杠方向),否则 switchTab 直接静默失败,控制台也不报错。
选中态同步靠路由监听,不是靠组件传值
很多人在页面里用 props 传 current 给 tabbar 组件,结果切换页面后状态丢失——因为页面卸载重载,props 重置了。正确做法是在 tabbar 组件内部用 watch: { '$route.path' } 或 onShow 生命周期读当前路径,查表映射成索引。例如建个对象 { '/pages/index/index': 0, '/pages/msg/msg': 1 },路径变了就立刻更新 current 值。否则用户从消息页右滑返回首页,tabbar 还亮着“消息”图标,体验断裂。
最易忽略的是安全区适配:bottom: 0 不够,得加 padding-bottom: env(safe-area-inset-bottom),不然 iPhone X 以上机型底部图标会被刘海遮半截。


















