为什么要自定义tabbar?
比如要实现下图这种效果,中间的按钮是凸出的,默认的就无法满足了。
采取的方案
微信官方文档提供了一个自定义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;
}