微信小程序自定义导航栏组件

微信小程序自定义导航栏组件


场景:在小程序项目开发过程中,遇到一个需求是导航栏及下面一块地方需要放一张背景图(整体),由于导航栏不支持配置图片,查阅相关资料,最终解决方案如下

在这里插入图片描述
1、在微信项目的app.json中配置windpw对象的navigationStyle属性为custom,此时所有页面导航都是自定义,仅保留右边胶囊
2、自定义导航组件,该组件需要适配各种机型及自定义返回按钮事件等
遇到的问题:
1、各种机型上如何让自定义的title上下居中,与胶囊在同一水平线上
2、组件公用返回事件如何定义
分析
在这里插入图片描述
在这里插入图片描述
上图是两个不同机型顶部导航栏效果图,要实现title栏上下居中,我们必须知道状态栏高度(刘海区域),及底部胶囊容器的高度(红色框)
通过微信官方接口可以获取到胶囊按钮高度A胶囊上边缘到顶部的距离B以及状态栏高度C
胶囊容器的高度 = A+(B-C)*2
官方接口
wx.getSystemInfo:该接口的返回参数包含C(statusBarHeight) 戳>>.
wx.getMenuButtonBoundingClientRect()该接口返回的参数包含A(height),B(top) 戳>>.
代码:

wx.getSystemInfo({  
      success: e => {  
          let StatusBar = e.statusBarHeight;  
          let rect = wx.getMenuButtonBoundingClientRect();  
          let HeaderBar = rect.height + (rect.top - e.statusBarHeight) * 2;  //胶囊容器高度
          let CustomBar = HeaderBar + e.statusBarHeight;  //胶囊容器高度加状态栏高度
          this.globalData.headerBarHeight = HeaderBar   
          this.globalData.customBarHeight = CustomBar   
      }  
  })

此段代码可以放到全局的app.js中,后续直接获取对应值使用
注:由于胶囊按钮是原生组件,为表现一致,其单位在各种手机中都为px,所以我们自定义导航栏的单位都必需是px(切记不能用rpx),才能完美适配。
整个导航组件代码:
wxml

<!--pages/components/navBar/navBar.wxml-->
<view class="nav-bar-box">
  <view class="login-com" wx:if="{{bgFlag}}">
    <view class="title" style="padding-top:{{statusBarHeight}}px;hieght:{{headerBarHeight}}px;line-height:{{headerBarHeight}}px">
      <text>登录</text>
    </view>
    <image src="{{imageHost + 'login-background.png'}}"></image>
  </view>
  <view class="other-com" wx:else>
    <view class="title" style="padding-top:{{statusBarHeight}}px;hieght:{{headerBarHeight}}px;line-height:{{headerBarHeight}}px;padding-right:{{back? '44': ''}}px">
      <view class="icon-wrap" wx:if="{{back}}" bindtap="onBack">
        <text class="icon iconfont iconfanhui"></text>
      </view>
      <view class="title-wrap">
        <text class="text">{{title}}</text>
      </view>
    </view>
  </view>
</view>

js

// pages/components/navBar/navBar.js
const { getApi, postApi, imageHost } = require("../../../utils/request")
const app = getApp()
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    title: {  //标题内容
      type: String,
      value: ''
    },
    bgFlag: {  //是否背景图
      type: Boolean,
      value: false
    },
    back: {  //返回按钮是否展示
      type: Boolean,
      value: false
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    imageHost,
    statusBarHeight: app.globalData.statusBarHeight,//自定义顶部栏高度
    headerBarHeight: app.globalData.headerBarHeight
  },

  /**
   * 组件的方法列表
   */
  methods: {
    onBack() {
      wx.navigateBack()
    }
  },
  options: {
    addGlobalClass: true
  }
})

wxss

/* pages/components/navBar/navBar.wxss */
.nav-bar-box image{
  height: 500rpx;
  width: 100%;
}
.nav-bar-box .login-com{
  position: relative;
}
.nav-bar-box .login-com .title{
  position: absolute;
  width: 100%;
  text-align: center;
  font-size: 36rpx;
  font-family: 'Source Han Sans CN';
  font-weight: 500;
  color: #222221;
}
.nav-bar-box .other-com{
  width: 100%;
  text-align: center;
  font-size: 36rpx;
  font-family: 'Source Han Sans CN';
  font-weight: 500;
  color: #222221;
  background-color: #BECFAA;
}
.nav-bar-box .other-com .title{
  position: relative;
  display: flex;
  padding: 0 24rpx;
  box-sizing: border-box;
  display: flex;
}
.nav-bar-box .other-com .icon-wrap{
  width: 20px;
}
.nav-bar-box .other-com .icon-wrap .icon{
  font-size: 40rpx;
}
.nav-bar-box .other-com .title-wrap{
  flex: 1;
  width: 1rpx;
  text-align: center;
}
.nav-bar-box .other-com .title-wrap .text{
  position: relative;
  transform: translate(-50%,-50%);
  font-size: 36rpx;
  font-family: 'Source Han Sans CN';
  font-weight: 500;
  color: #222221;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值