导读:本期聚焦于南京SEO公司创作的《微信小程序自定义tabBar如何实现图标选中态与未选中态的平滑过渡动画?》,敬请观看详情。小程序原生的tabBar样式定制能力有限,选中图标切换时往往显得生硬。想让选中和未选中状态之间有缩放、透明度渐变等平滑过渡效果,就需要启用custom属性来自定义整个tabBar。本文介绍如何在app.json中开启自定义tabBar,编写独立的tabbar组件,通过CSS transition和WXSS动效实现图标颜色渐变、文字渐显、徽标弹出等效果,同时处理好页面切换时的状态同步问题,避免出现图标状态与页面不匹配的常见坑,帮你打造视觉体验更流畅的底部导航栏。

小程序自带的tabBar虽然配置简单,但样式基本靠系统默认样式撑着,图标从灰色变成高亮色的那一瞬间没有任何过渡效果,切换起来总有种生硬的跳跃感。如果产品对视觉细节有要求,比如希望图标被选中时有一个轻微的放大回弹、文字颜色渐变、徽标数字弹跳出现,就必须走自定义tabBar的路线,用CSS过渡动画把这些细节做扎实。这篇文章从配置开启到组件编写,再到状态同步的坑,完整梳理一遍实现思路。

微信小程序自定义tabBar如何实现图标选中态与未选中态的平滑过渡动画?

一、开启自定义tabBar的正确配置

微信小程序从基础库2.5.0开始支持自定义tabBar,做法是在app.json的tabBar配置中加一个"custom": true字段。需要注意的是,即使启用了自定义tabBar,list数组里的页面配置也不能删掉,因为页面路由仍然依赖这份配置来判断哪些页面属于tab页,系统只是把渲染权交给你自己。

配置开启后,还要在代码根目录下新建一个custom-tab-bar文件夹(目录名必须一模一样,不能写成custom-tabbar),里面放index.js、index.json、index.wxml和index.wxss四个文件,相当于一个特殊的全局组件。看一下基础配置:

{
  "tabBar": {
    "custom": true,
    "color": "#999999",
    "selectedColor": "#07c160",
    "backgroundColor": "#ffffff",
    "list": [
      {
        "pagePath": "pages/index/index",
        "text": "首页"
      },
      {
        "pagePath": "pages/logs/logs",
        "text": "日志"
      }
    ]
  }
}

这份配置里的颜色字段在自定义模式下不会被直接渲染,但保留它们没有坏处,某些异常兜底场景下系统仍会读取这些值。真正决定视觉效果的是custom-tab-bar组件里的wxml和wxss。

二、编写tabbar组件并实现选中态过渡动画

组件的js部分核心工作是维护一个selected字段记录当前选中的索引,并提供一个setSelected方法供各页面调用。先看js和wxml:

// custom-tab-bar/index.js
Component({
  data: {
    selected: 0,
    color: '#999999',
    selectedColor: '#07c160',
    list: [
      { pagePath: '/pages/index/index', text: '首页', icon: 'home', badge: 0 },
      { pagePath: '/pages/logs/logs', text: '日志', icon: 'log', badge: 3 }
    ]
  },
  methods: {
    setSelected(index) {
      if (this.data.selected === index) return
      this.setData({ selected: index })
    }
  }
})
<view class="tab-bar">
  <view
    wx:for="{{list}}"
    wx:key="pagePath"
    class="tab-item"
    data-path="{{item.pagePath}}"
    data-index="{{index}}"
    bindtap="switchTab"
  >
    <view class="icon-wrap">
      <image class="icon {{selected === index ? 'active' : ''}}" src="{{selected === index ? item.iconActive : item.icon}}"/>
      <view wx:if="{{item.badge > 0}}" class="badge">{{item.badge}}</view>
    </view>
    <text class="label {{selected === index ? 'active' : ''}}">{{item.text}}</text>
  <!-- 点击切换页面 -->
  </view>
</view>

点击切换的逻辑要在wxml绑定一个switchTab事件,在js里通过wx.switchTab跳转,这里不再赘述。真正让切换"活起来"的是wxss里的过渡动画。关键技巧是:不要用两个图标做显示隐藏切换,而是给同一个元素切换class,让transform和opacity通过transition自然过渡:

.tab-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8rpx 0 4rpx;
}

.icon-wrap {
  position: relative;
  width: 52rpx;
  height: 52rpx;
}

.icon {
  width: 100%;
  height: 100%;
  opacity: 0.55;
  transform: scale(0.9);
  transition: transform 0.25s ease, opacity 0.25s ease;
}

.icon.active {
  opacity: 1;
  transform: scale(1.06);
}

.label {
  font-size: 22rpx;
  color: #999999;
  transition: color 0.25s ease;
}

.label.active {
  color: #07c160;
  font-weight: 600;
}

.badge {
  position: absolute;
  top: -10rpx;
  right: -16rpx;
  min-width: 30rpx;
  height: 30rpx;
  line-height: 30rpx;
  border-radius: 15rpx;
  background: #fa5151;
  color: #fff;
  font-size: 20rpx;
  text-align: center;
  animation: badgePop 0.3s ease;
}

@keyframes badgePop {
  0% { transform: scale(0); }
  60% { transform: scale(1.25); }
  100% { transform: scale(1); }
}

这段样式里做了三层动效:图标透明度和缩放同时过渡,视觉上是从灰色淡出到高亮并轻微放大;文字颜色平滑渐变;徽标用@keyframes做一个先放大再回落的弹跳。如果想要更明显的回弹手感,可以把transition的timing-function换成cubic-bezier(0.34, 1.56, 0.64, 1),这是常用的过冲曲线,图标会先超过目标大小再缩回来,动画感更强。另外要注意,改图标src属于资源替换,不会有过渡效果,所以选中态的视觉变化尽量靠transform和opacity表达,颜色变化交给文字和遮罩层完成。

三、页面切换时的状态同步:最容易踩的坑

自定义tabBar有一个经典问题:每个tab页面都会实例化一份独立的tabbar组件。用户从首页切到日志页时,日志页拿到的是自己那份初始状态为0的组件,如果不在页面里主动同步,图标就会停留在错误的高亮位置,动画再好看也白搭。

解决办法是在每个tab页面的onShow生命周期里获取组件实例并调用setSelected:

// pages/logs/logs.js
Page({
  onShow() {
    if (typeof this.getTabBar === 'function' && this.getTabBar()) {
      this.getTabBar().setSelected(1)
    }
  }
})

这里有两个细节值得注意。第一,getTabBar()只在tab页里存在,普通页面调用会报错,所以加一个函数存在性判断更稳妥。第二,把同步逻辑写在onShow而不是onLoad,因为tab页第一次加载后会被缓存,之后每次切回来只会触发onShow,写在onLoad里的话第二次切换就不会更新状态了。

还有一个体验层面的优化点:由于每次切换都会执行setData,组件重新渲染时动画会重新播放,这正是我们想要的效果——切换瞬间图标从上一次的选中态过渡到新状态。但如果你的setSelected里做了其他数据更新(比如拉取最新徽标数),要避免频繁setData大对象,否则在低端机上动画可能掉帧。建议把动画相关的class切换和业务数据更新拆成两次轻量的setData调用,保证动画字段优先更新。

总结一下整体思路:配置层开启custom,组件层用class切换配合transition做视觉过渡,页面层在onShow里同步索引。三层各司其职,就能得到一个图标渐变放大、文字变色、徽标弹跳的丝滑tabBar,而且完全可控,后续想加凸起中间按钮或者角标动画,都只是在这个结构上继续扩展样式而已。

微信小程序自定义tabBar过渡动画修改时间:2026-09-10 07:00:42

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/0910/53885.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。