问题背景
自定义 tabBar 可以让开发者更加灵活地设置 tabBar 样式,以满足更多个性化的场景。本文将介绍微信小程序开发中如何自定义tabbar。
问题分析
微信小程序中,自定义tabbar的流程如下:
- 配置信息 在 app.json 中的 tabBar 项指定 custom 字段,同时其余 tabBar 相关配置也补充完整。 所有 tab 页的 json 里需声明 usingComponents 项,也可以在 app.json 全局开启。demo代码如下:
{
"tabBar": {
"custom": true,
"color": "#000000",
"selectedColor": "#000000",
"backgroundColor": "#000000",
"list": [{
"pagePath": "page/component/index",
"text": "组件"
}, {
"pagePath": "page/API/index",
"text": "接口"
}]
},
"usingComponents": {}
}
- 添加 tabBar 代码文件,在代码根目录下新建custom-tab-bar目录,添加入口文件:
custom-tab-bar/index.js
custom-tab-bar/index.json
custom-tab-bar/index.wxml
custom-tab-bar/index.wxss
- 编写 tabBar 代码
问题解决
话不多说,直接上代码。 (1)项目app.json文件,代码如下:
{
"pages": [
"pages/index/index",
"pages/login/index",
"pages/logs/logs",
"pages/lll"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "Weixin",
"navigationBarTextStyle": "black"
},
"tabBar": {
"custom": true,
"color": "#626262",
"selectedColor": "#062da9",
"borderStyle": "black",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "static/img/icon-admin.png",
"selectedIconPath": "static/img/icon-admin.png",
"text": "首页"
},
{
"pagePath": "pages/login/index",
"iconPath": "static/img/icon-admin.png",
"selectedIconPath": "static/img/icon-admin.png",
"text": "企业诉求"
}
]
},
"style": "v2",
"sitemapLocation": "sitemap.json",
"usingComponents": {}
}
(2)项目根目录下新建的custom-tab-bar文件夹中,文件内容如下。 index.js文件,代码如下:
let app = getApp();
Component({
data: {
selected: 0,
color: "#626262",
selectedColor: "#062da9",
list: [{
"pagePath": "/pages/index/index",
"iconPath": "/static/img/icon-admin.png",
"selectedIconPath": "/static/img/icon-admin.png",
"text": "首页"
}, {
"pagePath": "/pages/login/index",
"iconPath": "/static/img/icon-admin.png",
"selectedIconPath": "/static/img/icon-admin.png",
"text": "分类"
},{
"pagePath": "/pages/my/my",
"iconPath": "/static/img/icon-admin.png",
"selectedIconPath": "/static/img/icon-admin.png",
"text": "我的"
}]
},
ready() {
},
attached() {
},
methods: {
switchTab(e) {
const data = e.currentTarget.dataset
const url = data.path
wx.switchTab({url})
this.setData({
selected: data.index
})
}
}
})
index.json文件,代码如下:
{
"component": true
}
index.wxml文件,代码如下:
<view class="navigation-container" style="{{'height: ' + navigationBarAndStatusBarHeight}}">
<!--空白来占位状态栏-->
<view style="{{'height: ' + statusBarHeight}}"></view>
<!--自定义导航栏-->
<view class="navigation-bar" style="{{'height:' + navigationBarHeight}}">
<view class="navigation-title" style="{{'line-height: ' + navigationBarHeight}}">测试首页</view>
</view>
</view>
<!--空白占位fixed空出的位置-->
<view style="{{'height: ' + navigationBarAndStatusBarHeight}}; background: #ffffff"></view>
<scroll-view scroll-y="{{true}}" class="pageWrapper" style="height:calc(100% - {{navigationBarAndStatusBarHeight }} - {{tabbarAndBottomSafeHeight + 'px'}});">
<view class="index-bg">
<image src="../../static/img/bg_guanggu.png" style="width:100%;height:100%"></image>
</view>
<swiper class="swiper-block" circular="true" duration="1000" autoplay="true" interval="3000" previous-margin="60rpx" next-margin="60rpx" bindchange="swiperChange" current="{{adIndexIndex}}">
<block wx:for="{{homeBannerList}}" wx:key="id" wx:index="{{index}}">
<swiper-item class="swiper-item">
<view class="slide-image {{adIndexIndex == index ? 'active' : ''}}" style="position:relative">
<image mode="scaleToFill" style="width:100%;height:100%" src="{{item}}" />
<!-- <view class="bannerdesc">{{item.imgName}}</view> -->
</view>
</swiper-item>
</block>
</swiper>
<view class="swiper-nav">
<view wx:for="{{homeBannerList}}" wx:key="id" wx:index="{{index}}" class='navclass' bindtap="navtap" data-index="{{index}}">
<image style="width:90%;height:100%" wx:if="{{index==adIndexIndex}}" src="../../static/img/nav2.png"></image>
<image style="width:46%;height:100%" wx:else src="../../static/img/nav.png"></image>
</view>
</view>
<view class="firstTitle">
中心简介
</view>
<view style="margin-left: 30rpx; width:690rpx;height:140rpx" bindtap="goServiceCenter">
<image src="../../static/img/banner.png" mode="scaleToFill" style="width:100%;height:100%"></image>
</view>
<view class="firstTitle">
公告资讯
</view>
<view class='cont-title flexbetween'>
<scroll-view style="width:70%" scroll-x="true">
<view class='menutabbox1'>
<block wx:for="{{categorys}}" wx:for-item="item" wx:key="index">
<view class="menuitem {{item.active? 'itemactive': ''}}" bind:tap="changetype" data-id="{{item.id}}" data-index="{{index}}">
<text class="label-title">{{item.name}}</text>
<!-- <view></view> -->
</view>
</block>
</view>
</scroll-view>
<view style="margin:0 10rpx" style="color:#000000">|</view>
<view style="position:relative;">
<text bindtap='getAllNotice' style="color:#999999">查看全部</text>
</view>
</view>
<swiper snap-to-edge="true" previous-margin="20rpx" next-margin="20rpx" style="margin-left: 15rpx; width:720rpx;height:450rpx" current="{{publishCurr}}" wx:if="{{publishInfoList.length > 0}}">
<swiper-item class="" wx:for="{{ publishInfoList }}" wx:for-item="item" wx:key="index">
<view style="height:90%;box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);margin:20rpx 20rpx;">
<view class='infobox'>
<view style="width:100%;height: 50%;border-bottom: 1rpx solid #f0f0f0;" class="flexbetween" data-title="资讯详情" data-id="{{item.id}}" bindtap='goDetail'>
<view style='width:calc(100% - 236rpx);'>
<view class='info-title'>{{item.name}}</view>
<view class='itemflex'>
<image src="../../static/img/icon-admin.png" mode="widthFix" class='icon1'></image>
<text class='info-text'>{{item.lat}}</text>
<image src="../../static/img/icon-eye.png" mode="widthFix" class='icon2'></image>
<text class='info-text'>{{item.lon}}</text>
</view>
</view>
<view class="info-img" style="display:flex; align-items:center;overflow-y:hidden;background-color:#f5f5f5;border-radius: 10rpx">
<image wx:if="{{item.adm1}}" style="width:100%;height:100%" src="../../static/img/icon-admin.png" mode="scaleToFill"></image>
<image wx:else style="width:100%;height:100%" src="../../static/img/default_pic.jpg" mode="scaleToFill"></image>
</view>
</view>
<view wx:if="{{item.length > 1}}" style="width:100%;height: 50%;" class="flexbetween" data-title="资讯详情" data-id="{{item.id}}" bindtap='goDetail'>
<view style='width:calc(100% - 236rpx);'>
<view class='info-title'>{{item.name}}</view>
<view class='itemflex'>
<image src="../../static/img/icon-admin.png" mode="widthFix" class='icon1'></image>
<text class='info-text'>{{item.lat}}</text>
<image src="../../static/img/icon-eye.png" mode="widthFix" class='icon2'></image>
<text class='info-text'>{{item.lon}}</text>
</view>
</view>
<view class="info-img" style="display:flex; align-items:center;overflow-y:hidden;background-color:#f5f5f5;border-radius: 10rpx">
<image wx:if="{{item.name}}" style="width:100%;height:100%" src="../../static/img/icon-eye.png" mode="scaleToFill"></image>
<image wx:else style="width:100%;height:100%" src="../../static/img/default_pic.jpg" mode="scaleToFill"></image>
</view>
</view>
</view>
</view>
</swiper-item>
</swiper>
<view style="width:95%;height:200rpx;display: flex;justify-content: center;font-size: 48rpx;line-height: 200rpx;" wx:if="{{publishInfoList.length == 0}}">
暂无任何资讯
</view>
<view class="firstTitle">
常见办事入口
</view>
<scroll-view scroll-x="true" style="margin-left: 20rpx; width: 710rpx;background-color: #f7f7f7;">
<view class="menutabbox1 " style="height: 200rpx;padding:0;">
<view class="legalinfoitem" style="padding: 0 40rpx;" wx:for="{{publishInfoList}}" wx:key="index" bindtap="goMini" data-entertype="{{item.adm2}}" data-content="{{item.adm1}}">
<image src="../../static/img/icon-eye.png" style="width:99rpx;height:99rpx;border-radius: 50%;" mode="scaleToFill"></image>
<text style="color: #333333;font-size: 22rpx; text-align: center;">{{item.name}}</text>
</view>
</view>
</scroll-view>
<view class="firstTitle">
建议意见
</view>
<view class="zxfw" style="margin-bottom:50rpx">
<view class="zxfw1" bindtap="goComplain" data-type="1">
<image src="../../static/img/icon-admin.png" style="width:100%;height:100%"></image>
</view>
<view class="zxfw1" bindtap="goComplain" data-type="2">
<image src="../../static/img/icon-admin.png" style="width:100%;height:100%"></image>
</view>
</view>
<view class="contactus" bindtap="goContactUs" style="bottom:{{tabbarAndBottomSafeHeight + 15}}px">
<image src="../../static/img/icon-eye.png" style="width:100%;height:100%"></image>
</view>
</scroll-view>
index.wxss文件,代码如下:
.swiper-block{
height: 400rpx;
width: 100%;
margin-top: 50rpx;
z-index: 10;
}
.swiper-item{
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
overflow:unset;
}
.slide-image{
height:380rpx;
width: 90%;
border-radius: 9rpx;
/* box-shadow: 0px 0px 30rpx rgba(0, 0,0,.2); */
margin: 0rpx 30rpx;
z-index: 1;
}
.active{
transform: scale(1.14);
transition:all .2s ease-in 0s;
z-index: 20;
}
.navclass{
width: 40rpx;
height: 12rpx;
display: flex;
justify-content: center;
align-items: center;
margin-top: 30rpx;
}
/* 导航 */
.navigation-container {
position: fixed;
width: 100%;
z-index: 99;
top: 0;
left: 0;
background-color: #ffffff;
}
.navigation-bar {
position: relative;
display: flex;
flex-direction: row;
align-items: center;
}
.navigation-title {
position: absolute;
left: 104px;
right: 104px;
text-align: center;
font-size: 16px;
font-weight: bold;
color: #000000;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.index-bg{
width: 100%;
height: 450rpx;
z-index: 0;
position: absolute;
top: 0;
left: 0;
}
.pageWrapper{
height: 100%;
width: 100%;
/* display: flex;
flex-direction: column;
align-items: center; */
overflow-x: hidden;
}
.swiper-nav{
width: 100%;
height: 12rpx;
display: flex;
justify-content: center;
align-items: center;
z-index: 10;
}
.firstTitle{
width: 95%;
position: relative;
margin: 30rpx 0;
padding-left: 60rpx;
font-weight: bold;
}
.firstTitle::before{
position:absolute;
content: " ";
height: 100%;
width: 10rpx;
background-color: #062da9;
left: 5%;
}
.cont-title {
width: 100%;
height: 90rpx;
padding: 0 40rpx;
border-bottom: solid 2rpx #f0f0f0;
color: #0d91ff;
font-size: 28rpx;
line-height: 80rpx;
box-sizing: border-box;
}
.cont-title text {
line-height: 80rpx;
}
.flexbetween {
display: flex;
align-items: center;
justify-content: space-between;
}
.menutabbox1 {
padding: 0 30rpx;
box-sizing: border-box;
display: flex;
width: 100%;
color: #666666;
}
.menuitem {
width: auto;
height: 100%;
background: #fff;
}
.label-title {
display: inline-block;
padding: 0 20rpx;
white-space: nowrap;
font-size: 28rpx;
}
.itemactive {
color: #062da9;
font-weight: 600;
}
.infobox:first-child {
border-top: none;
}
.infobox {
width: calc(100% - 40rpx);
height: 100%;
margin-left: 40rpx;
padding: 20rpx 40rpx 20rpx 0;
border-bottom: solid 2rpx #f0f0f0;
box-sizing: border-box;
position: relative;
}
.info-title {
font-family: SourceHanSansCN-Medium;
font-size: 30rpx;
font-weight: bold;
font-stretch: normal;
line-height: 45rpx;
letter-spacing: 0rpx;
color: #000000;
overflow: hidden;
white-space: nowrap; /*不换行 */
text-overflow: ellipsis;
}
.itemflex {
display: flex;
align-items: center;
margin-top: 28rpx;
}
.info-text {
color: #aebdd8;
font-size: 20rpx;
margin-left: 5rpx;
}
.icon1 {
width: 17rpx;
height: 21rpx;
}
.icon2 {
width: 24rpx;
height: 15rpx;
margin-left: 20rpx;
}
.info-img {
width: 236rpx;
height: 133rpx;
}
.menutabbox1 {
padding: 0 30rpx;
box-sizing: border-box;
display: flex;
width: 100%;
color: #666666;
}
.legalinfoitem{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
}
.zxfw{
margin-left: 30rpx;
width: 690rpx;
height: 350rpx;
display: flex;
align-items: center;
justify-content: space-around;
}
.zxfw1{
width: 40%;
height: 280rpx;
}
.contactus{
height: 150rpx;
width: 145rpx;
position: fixed;
right: 20rpx;
}
运行结果如下:
问题总结
本文初步介绍了微信小程序开发中如何自定义tabbar,有兴趣的同学可以进一步深入研究。
标签:index,center,自定义,flex,微信,100%,程序开发,height,width From: https://blog.51cto.com/baorant24/6206364