问题引出:
传统的tabbar:
样式和布局固定,缺乏灵活性和个性化,难以满足不同用户的需求。
功能较为单一,无法实现多窗口的切换和自定义功能,难以满足复杂的应用场景。
大多数的小程序具有发布的功能,想要实现突出的加号的发布按钮的实现,针对这些问题可以设计自定义的tabbar
如何实现
微信的官方api中其实是有自定义tabbar的介绍的
自定义taibbar
只是这里需要一些注意点,不注意的话会导致不能正确显示的问题
实现案例
效果如下:
一、官方文档中提到,需要
这里是第一个注意点,这里的custom-tab-bar必须为这个名字,否则不生效,放在pages的同级目录下,这个custom-tab-bar是在miniprogram下面新建component,具体的目录结构如下:
首先需要配置app.json
{
"pages": [
"pages/index/index",
"pages/publish/publish",
"pages/mine/mine",
"pages/msg/msg",
"pages/shopping/shopping"
],
"window": {
"backgroundColor": "#F6F6F6",
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#F6F6F6",
"navigationBarTitleText": "师大闲置物品交易",
"navigationBarTextStyle": "black"
},
"sitemapLocation": "sitemap.json",
"style": "v2",
"tabBar": {
"custom": true,
"list": [
// 这里的pagePath要有,即使是自定义的,如果没有会报错
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "static/icon/home.png",
"selectedIconPath": "static/icon/home-fill.png"
},
{
"pagePath": "pages/shopping/shopping",
"text": "商城",
"iconPath": "static/icon/shopping.png",
"selectedIconPath": "static/icon/shopping.png"
},
{
"pagePath": "pages/publish/publish",
"text": "发布",
"iconPath": "static/icon/plus-circle.png",
"selectedIconPath": "static/icon/plus-circle-fill.png"
},
{
"pagePath": "pages/msg/msg",
"text": "消息",
"iconPath": "static/icon/message.png",
"selectedIconPath": "static/icon/message-fill.png"
},
{
"pagePath": "pages/mine/mine",
"text": "我的",
"iconPath": "static/icon/user.png",
"selectedIconPath": "static/icon/user -fill.png"
}
]
}
}
index.wxml如下:
<!--components/custom-tab-bar.wxml-->
<view class="tab-bar flex_row">
<!-- <view class="tab-bar-border"></view> -->
<block wx:for="{{list}}" wx:key="index" >
<!-- 中心圆 -->
<view class="tab-bar-item flex_colum tabbar_circle " wx:if="{{index==2}}" data-url="{{item.pagePath}}" data-index="{{index}}" bind:tap="onchange">
<image src="{{'/'+item.iconPath}}" mode="aspectFill"/>
<view class="tabbartext">{{item.text}}</view>
</view>
<!-- 其余 -->
<!-- 这里的selected不能在onchange里面修改 -->
<view class="tab-bar-item flex_colum {{selected==index && 'select'}}" wx:else="" data-url="{{item.pagePath}}" data-index="{{index}}" bind:tap="onchange">
<block wx:if="{{selected===index}}">
<image class="tabbaritem_icon" src="{{'/'+item.selectedIconPath}}" mode="aspectFill"/>
</block>
<block wx:else="">
<image class="tabbaritem_icon" src="{{'/'+item.iconPath}}" mode="aspectFill"/>
</block>
<view class="tabbartext">{{item.text}} </view>
</view>
</block>
</view>
index.wxs
// components/custom-tab-bar.js
Component({
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
/*这里需要跟tabbar中定义的一样*/
data: {
selected:0,
list:[
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "static/icon/home.png",
"selectedIconPath": "static/icon/home-fill.png"
},
{
"pagePath": "pages/shopping/shopping",
"text": "商城",
"iconPath": "static/icon/shopping.png",
"selectedIconPath": "static/icon/shopping-fill.png"
},
{
"pagePath": "pages/publish/publish",
"text": "发布",
"iconPath": "static/icon/plus-circle.png",
"selectedIconPath": "static/icon/plus-circle-fill.png"
},
{
"pagePath": "pages/msg/msg",
"text": "消息",
"iconPath": "static/icon/message.png",
"selectedIconPath": "static/icon/message-fill.png"
},
{
"pagePath": "pages/mine/mine",
"text": "我的",
"iconPath": "static/icon/user.png",
"selectedIconPath": "static/icon/user-fill.png"
}
]
},
/**
* 组件的方法列表
*/
methods: {
onchange(e){
let res=e.currentTarget.dataset
console.log(res)
console.log(res.url);
console.log(res.index);
/*这种方式设置值会出错,变化的
this.setData({
selected:res.index
});*/
/*用下面的函数跳转页面*/
wx.switchTab({
url: "/"+res.url/*注意这里得到的目录跟前面的一样,前面不带杠/*/
})
}
}
})
css
.tab-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 48px;
background: white;
display: flex;
padding-bottom: env(safe-area-inset-bottom);
}
.tab-bar-border {
background-color: rgba(0, 0, 0, 0.33);
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 1px;
transform: scaleY(0.5);
}
.tab-bar-item {
flex: 1;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.tab-bar-item image {
width: 27px;
height: 27px;
}
.tab-bar-item view {
font-size: 10px;
}
.tabbar_circle {
display: block;
position: relative;
}
.tabbar_circle image {
flex-shrink: 0;
width: 100rpx;
height: 100rpx;
position: absolute;
top: -50rpx;
left: calc(50% - 50rpx);
border-radius: 50%;
box-shadow: 0 0 5px #999;
background-color: #ffffff;
}
.tabbar_circle .tabbartext {
position: absolute;
bottom: 15rpx;
left: 32%
}
到每个tabbar页面注册判断、调整当前选中颜色,js文件中
Component({
pageLifetimes: {
show() {
if (typeof this.getTabBar === 'function' &&
this.getTabBar()) {
this.getTabBar().setData({
selected: 0
})
}
}
}
})