微信小程序开发自定义tabbar

微信小程序开发自定义tabbar

问题背景

自定义 tabBar 可以让开发者更加灵活地设置 tabBar 样式,以满足更多个性化的场景。本文将介绍微信小程序开发中如何自定义tabbar。

问题分析

微信小程序中,自定义tabbar的流程如下:

  1. 配置信息
    在 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": {}
}
  1. 添加 tabBar 代码文件,在代码根目录下新建custom-tab-bar目录,添加入口文件:
custom-tab-bar/index.js
custom-tab-bar/index.json
custom-tab-bar/index.wxml
custom-tab-bar/index.wxss
  1. 编写 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,有兴趣的同学可以进一步深入研究。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值