做微信小程序的人应该都配过 tabBar。看着文档好像挺简单,就几个字段,实际写起来总会有这样那样的问题。这篇文章把 tabBar 的配置细节和新手容易踩的坑梳理一遍。

tabBar 的基本结构

tabBar 配置写在 app.json 文件里,跟 pages、window 这些字段同级。一个最基础的 tabBar 长这样:

{
  "tabBar": {
    "list": [
      {
        "pagePath": "pages/index/index",
        "text": "首页",
        "iconPath": "images/home.png",
        "selectedIconPath": "images/home-active.png"
      },
      {
        "pagePath": "pages/profile/profile",
        "text": "我的",
        "iconPath": "images/profile.png",
        "selectedIconPath": "images/profile-active.png"
      }
    ]
  }
}

list 数组里放的是每个 tab 项的配置,最少 2 个,最多 5 个。这是微信的限制,不能多也不能少。

list 字段详解

pagePath

页面路径,对应 pages 数组里注册过的页面。这个字段必须以 "pages/" 开头,而且这个页面必须在 app.json 的 pages 字段中声明过。如果 pagePath 指向一个未注册的页面,编译器不会报错,但运行时点击那个 tab 会白屏或者跳转失败。

text

tab 上显示的文字。建议控制在 4 个汉字以内,太长了在小屏幕上显示不全会被截断。文字内容没有特别限制,但一般用简洁的名词比较好,比如"首页"、"发现"、"我的"这种。

iconPath 和 selectedIconPath

这两个分别是未选中和选中状态下的图标路径。图标必须是本地图片,不支持网络地址。图片格式支持 png、jpg 等,建议用 png 透明背景。尺寸方面,官方推荐 81x81 像素,实际上只要正方形、不太大就行。

iconPath 是默认状态(灰色),selectedIconPath 是选中状态(一般是主题色)。如果两个图标的颜色或样式差别不大,用户可能看不出来当前在哪个 tab,所以设计上要有明显的视觉区分。

color 和 selectedColor

控制 tab 文字的颜色。color 是未选中时的文字颜色(通常是灰色),selectedColor 是选中时的颜色(一般跟 App 的主色调一致)。颜色值用十六进制表示,比如 "#999999" 和 "#07C160"。

backgroundColor

tabBar 背景色,一般用白色或者浅灰色。注意这个背景色是整个底部导航栏的背景,不是单个 tab 的背景。

position

tabBar 的位置,可选值是 "bottom"(默认)和 "top"。大部分小程序用的是底部导航栏,顶部的情况比较少。需要注意的是,当 position 设为 top 时,不显示图标,只显示文字。所以如果你把位置改到顶部,iconPath 和 selectedIconPath 这两个字段虽然还要写,但实际上不会生效。

tabBar 配置新手常犯哪些错误

错误一:pagePath 未注册

这是最常见的坑之一。你在 tabBar 的 list 里写了 "pages/settings/settings",但是忘记在 app.json 的 pages 数组里添加这个路径。开发工具可能不会立刻报错,但真机上点进去就是空白页。每次加新 tab 的时候,先检查 pages 数组有没有对应的条目。

错误二:图标路径写错

图标路径是相对于项目根目录的。如果你把图片放在了 pages/index/images/ 下面,那 path 应该写成 "pages/images/xxx.png",而不是 "images/xxx.png"。另外要注意大小写,Windows 开发的时候可能不区分大小写,但在 macOS 或者构建后的环境里路径大小写是敏感的。

错误三:list 项数量不对

list 最少 2 个,最多 5 个。写成 1 个的话 tabBar 不显示;写成 6 个以上的话只会取前 5 个,多的被忽略。有些开发者想做一个只有首页和我的两个 tab 的极简结构,这没问题;但如果想做一个有七八个入口的复杂导航,tabBar 搞不定,得考虑用自定义组件或者其他导航方案。

错误四:tabBar 页面不能是带参数的路径

pagePath 只能是静态路径,不支持传参。比如 "pages/detail/detail?id=123" 这种写法是不允许的。tabBar 页面都是固定的几个主要入口,带参数的跳转逻辑放在普通页面里通过 wx.navigateTo 或 wx.redirectTo 来实现。

错误五:tabBar 页面之间不能用 navigateTo 跳转

这是一个比较隐蔽的问题。tabBar 页面之间切换要用 wx.switchTab,不能用 wx.navigateTo 或 wx.redirectTo。如果你在代码里用了后者,跳转不会生效或者会报错。同样,tabBar 页面只能作为目标页面存在,不能被非 tabBar 页面通过 navigateTo 打开(除非本身就是当前激活的 tab)。

position=top 有什么特殊处理

前面提到过,position 设为 top 时只显示文字不显示图标。这个设计是有原因的:顶部 tabBar 占用的屏幕空间有限,放图标会导致布局很挤。而且顶部导航栏通常已经有标题了,再加图标显得冗余。

使用顶部 tabBar 时要注意几点:图标路径还是必须填(虽然不显示),否则可能校验不通过;文字不要太长;顶部 tabBar 的样式跟底部不完全一样,比如分割线的处理方式不同。建议在真机上测试一下效果,模拟器和真机可能有细微差异。

快速生成配置的工具

手动写 JSON 配置不难,但要准备图标、调颜色、对路径这些事情还是挺繁琐的,特别是第一次配或者要频繁修改的时候。可以用TabBar 配置生成器来辅助,填好基本信息后自动生成标准的 JSON 配置代码,直接复制到 app.json 就能用。另外如果要同时处理 app.json 里的其他配置项,也可以用app.json 生成器来统一管理。

常见问题

tabBar 图标显示不出来怎么办?

检查三个常见原因:一是图片路径是否正确(相对路径从项目根目录开始写);二是图片格式是否支持(只支持 PNG 和 JPEG,不支持 SVG);三是图片尺寸是否符合要求(建议 81×81 像素,最大不超过 40KB)。

tabBar 能动态修改吗?

可以用 wx.setTabBarItem() 动态修改单个标签的文字和图标,用 wx.setTabBarStyle() 修改整体样式。但标签的数量和顺序不能动态改变,这些在 app.json 里写死了,运行时只能改内容。

自定义 tabBar 和原生 tabBar 有什么区别?

原生 tabBar 是 app.json 配置的,性能好但定制性有限。自定义 tabBar 需要在 app.json 设置 "custom": true,然后提供一个自定义组件来实现,可以实现更复杂的 UI 效果,但性能略差,开发成本也更高。

小结

tabBar 配置本身不复杂,但细节比较多。核心要点记住这几个:list 项要在 2-5 个之间;pagePath 必须在 pages 里注册过;图标只能是本地图片;position=top 时不显示图标;tabBar 页面之间用 switchTab 跳转。把这些注意到了,基本就不会出什么问题。

TabBar 配置工具

打开 TabBar 配置工具 →