小程序自定义tabbar附代码

594 阅读3分钟

为什么要自定义tabbar?

比如要实现下图这种效果,中间的按钮是凸出的,默认的就无法满足了。 image.png

采取的方案

微信官方文档提供了一个自定义tabbar的例子 文档说明还是要看下的,里面也供了代码片段

但是实际开发还是会遇到不少问题,下面几个需要注意的点:

遇到的问题和解决方案

必须在根目录下的指定文件夹 这个自定义tabbar组件必须放在根目录的custom-tab-bar文件夹下,这样才能被识别。

iphonex以上手机底部tab适配 Phonex以上手机的tabbar的高度是比较高和其它的手机是不一样的,需要自己做一下高度的适配。

小程序的基础库问题 自定义tabbar支持的小程序基础库版本是2.5.0,所以我们需要注意一下老基础库版本的兼容性问题。在低基础库的小程序上,自定义tabbar是可以在小程序的后台设置最低的基础库要求。

tabbar闪动 因为在切换tab的时候,必须setdata,所以肯定有闪动的,这个目前还没有找到很好的办法。

最后

附上tabbar自定义组件代码

<!--miniprogram/custom-tab-bar/index.wxml-->
<cover-view class="tab-bar {{isIphoneX ? 'barH' : ''}}">
  <cover-view class="tab-bar-inner">
    <cover-view 
      wx:for="{{list}}"
      wx:key="index" 
      class="tab-bar-item"
      data-path="{{item.pagePath}}"
      data-index="{{index}}"
      bindtap="switchTab" >
        <cover-image src="{{selected === index ? item.selectedIconPath : item.iconPath}}"></cover-image>
        <cover-view 
          style="color: {{selected === index ? selectedColor : color}}">
          {{item.text}}</cover-view>
    </cover-view>
    
  </cover-view>
  <cover-view class="tab-bar-bg"></cover-view>
</cover-view>
let app = getApp();
import { getMsginfo } from '../utils/util'

Component({
    /**
   * 组件的属性列表
   */
  properties: {
    // 是否选中
    on:{
      type: String,
      value: ''
    },
    current: {
        type: Number,
        value: 0
    }
  },
  data: {
    isIphoneX: false,
    selected: 0,
    color: "#999",
    backgroundColor: "#fff",
    selectedColor: "#1FC295",
    isShow: false,
    list: [
      {
        "pagePath": "/pages/index/index",
        "iconPath": "/public/images/tabbar/home.png",
        "selectedIconPath": "/public/images/tabbar/home_active.png",
        "text": "首页"
      },
      {
        "pagePath": "/pages/search/search",
        "iconPath": "/public/images/tabbar/search.png",
        "selectedIconPath": "/public/images/tabbar/search_active.png",
        "text": "搜索"
      },
      {
        "pagePath": "/pages/index/index",
        "iconPath": "/public/images/tabbar/play.png",
        "selectedIconPath": "/public/images/tabbar/play.png",
        "text": ""
      },      
      {
        "pagePath": "/pages/music/music",
        "iconPath": "/public/images/tabbar/music.png",
        "selectedIconPath": "/public/images/tabbar/music_active.png",
        "text": "曲库"
      },
      {
        "pagePath": "/pages/users/index",
        "iconPath": "/public/images/tabbar/my.png",
        "selectedIconPath": "/public/images/tabbar/my_active.png",
        "text": "个人中心"
      }
    ]
  },
  lifetimes: {
    attached () {
      // 在组件实例进入页面节点树时执行
      this.setData({
        isIphoneX: app.globalData.isIphoneX // 判断是不是IphoneX
      })
      // console.log('isIphoneX',this.data.isIphoneX)
    }
  },
  methods: {
      switchTab(e) {
          const data = e.currentTarget.dataset;
          const url = data.path;
          const index = data.index;
          let token = wx.getStorageSync("YSStoken")
          // 个人中心消息推送
          if (index !== 1) {
            getMsginfo()
          }
          if (index === 4 || index === 2) {
            if (token) {
              if (index === 2) {
                // 中间的播放菜单,不需要底部菜单,需要跳转到非tab页
                wx.navigateTo({
                  url: "/pages/play/play"
                })
              } else {
                wx.switchTab({ url });
              }
            } else {
              this.setData({
                isShow: true
              })
            }
          } else {
            wx.switchTab({ url });
          }
          this.setData({
            selected: index
          })
          console.log("当前点击是是第几个菜单" + index)
       
        }
    }

})

.tab-bar {
  position: fixed;
  z-index: 10;
  bottom: 0;
  left: 0;
  right: 0;
  height: 152rpx;
  display: flex;
  padding-bottom: env(safe-area-inset-bottom);
}
.tab-bar.barH {
  height: 220rpx;
}
.barH .tab-bar-inner {
  height: 168rpx;
}
.barH .tab-bar-bg {
  height: 168rpx;

}
.barH .tab-bar-border {
  bottom: 168rpx;
}
.tab-bar-bg {
  display: flex;
  position: absolute;
  left: 0;
  bottom: 0;
  margin-top: 52rpx;
  width: 100%;
  height: 130rpx;
  background: #fff;
}
.tab-bar-inner {
  display: flex;
  width: 100%;
  height: 152rpx;
  position: absolute;
  z-index: 3;
  left: 0;
  bottom: 0;
  overflow: visible;
}

.tab-bar-item {
  position: relative;
  z-index: 10;
  top: 0;
  flex: 1;
  text-align: center;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  color:#85879F;
}
.tab-bar-item.active  cover-view {
  color: #1FC295;
}
.tab-bar-item cover-image {
  width: 40rpx;
  height: 41rpx;
  margin-bottom: 5rpx;
}
.tab-bar-item:nth-child(1) cover-image {
  height: 37rpx;
}
.tab-bar-item:nth-child(2) cover-image {
  height: 39rpx;
}
.tab-bar-item:nth-child(3){
  top: -32rpx;
}
.tab-bar-item:nth-child(3) cover-image {
  width: 104rpx;
  height: 104rpx;
  margin-bottom: 0rpx;
}

.tab-bar-item cover-view {
  font-size: 20rpx;
}