原生 tabBar 不支持运行时动态换图,因其设计限制;需改用自定义 TabBar:通过 v-for 渲染 tab 项,:src 绑定图标变量,点击更新 currentIndex 并配合 uni.switchTab 跳转,图标资源须放 static/ 目录下。

原生 tabBar 不支持点击后动态换图——这不是你代码写错了,是它的设计限制。想真正在运行时响应点击、登录、主题切换等行为来换图标,必须放弃 pages.json 里的原生配置,改用自定义 TabBar。
为什么 uni.setTabBarItem 不适合“点击切换图标”
这个 API 确实能改单个 tab 的 iconPath 和 selectedIconPath,但它有硬伤:
- 调用后页面会闪一下(尤其 iOS 小程序),视觉上就是白屏或跳动
- 只能改一个 tab 项,没法批量同步更新全部图标状态
- 改完不触发重新渲染逻辑,比如红点数量变化、角标文字更新,得额外手动处理
- App 端部分机型(尤其是 Android 旧版本)根本不响应该调用
它适合的场景仅限于:冷启动时根据用户角色“一次性初始化”某个 tab 图标,而不是交互过程中的频繁切换。
自定义 TabBar 中如何绑定点击并切换图标
核心思路是用 v-for 渲染 tab 列表,每个 tab 的图标通过 :src 绑定变量,点击时更新当前激活索引,再靠计算属性返回对应图标路径或 iconfont 字符。
- 图标资源必须放在
static/目录下(如static/icons/home-active.png),不能用@/assets或相对路径 - 如果用 iconfont,需在
app.vue或全局样式中引入字体文件,并确保各平台都支持@font-face(H5 没问题,小程序需确认是否开启 base64 内联) - 不要在
data里直接写死所有图标路径数组,建议抽成配置对象,例如:{ home: { normal: 'static/icons/home.png', active: 'static/icons/home-active.png' } } - 点击事件里必须调用
uni.switchTab({ url: '/pages/home/home' }),不能只改本地状态,否则页面不会跳转
示例片段:
<image :src="tabIcons[currentIndex].active" v-if="index === currentIndex" /> <image :src="tabIcons[currentIndex].normal" v-else />
用 iconfont 实现颜色/图标联动切换的关键点
pages.json 原生支持 iconfont 配置,但仅限静态;要真正“动态”,就得在自定义组件里用 CSS 控制 color 和伪类 ::before 的 content 值。
- 每个 tab 项用一个
<text>标签,设置class="iconfont"并绑定 Unicode 字符,如<text class="iconfont" :decode="true">{{ currentIcon }} -
currentIcon是计算属性,根据currentIndex返回不同 Unicode,例如'\ue601'(首页)、'\ue602'(我的) - 选中态颜色用
.iconfont.active { color: #ff6b35; }控制,无需换图 - H5 端注意
text标签默认行高和垂直居中问题,加line-height: 1;和vertical-align: middle;
这种方案下,“点击切换图标”本质是切换字符和颜色,毫秒级无感,且主题色一改全改。
容易被忽略的兼容性陷阱
很多开发者卡在“图标显示为空”或“颜色没生效”,其实不是逻辑问题,而是环境细节没对齐:
- 微信小程序里,iconfont 字体文件必须是
.ttf格式,且上传时不能压缩(uni-app 构建会自动转 base64,但若手动放了压缩版 ttf,iOS 会拒载) - App 端 Android 对字体路径大小写敏感,
iconfont.ttf和IconFont.ttf是两个文件 - pages.json 中启用 iconfont 后,
iconPath字段必须填空字符串"",否则原生层会优先加载图片,覆盖字体 - 自定义 TabBar 在 H5 端要用
position: fixed; bottom: 0;,但需加z-index: 999;,否则被某些 UI 框架的遮罩层盖住
最麻烦的一点:如果你项目里同时用了 uView 的 u-tabbar 组件,它内部也依赖 uni.switchTab,但会劫持路由跳转逻辑——此时你自己的点击事件可能被吞掉,得看它源码里是否暴露了 bind:change 回调。


















