美文网首页
小程序自定义navBar

小程序自定义navBar

作者: smallzip | 来源:发表于2020-05-31 17:31 被阅读0次

业务需求,官网自带的navBar并不符合当前业务,所以需要使用自定义navBar来实现UI设计稿的样式需求。

首先我们来看看效果

类型2 类型1 类型3

当前业务只用到了这三种类型,下面我们就分析一下如何实现。

第一步

要使用自定义navBar需要在根目录的app.json当中找到“window”配置项,添加"navigationStyle": "custom"

开启自定义navBar

第二步

接下来我们就可以开心的使用自定义navbar了。
但是,先别开心的太早,上一步设置了"navigationStyle": "custom"之后,刷新页面发现,默认的navbar头部导航没有了,头部现在什么都没有。
那这就需要我们自己去编写navbar组件了。

第三步

在根目录新建一个components文件夹,新建好之后把鼠标焦点放在components位置右键再新建一个文件夹,我们命名为navbar,最后在navbar文件夹下新建一个component,命名为index。

新建component

最后的目录结构就是这样的啦~~


结构

第四步

组件我们已经新建好了,接下来就开始编写组件啦~
第一个我们会遇到的问题就是,如何判断这个navbar导航栏的高度。小程序的导航栏高度由两块组件,一个是状态栏的高度,一个导航栏高度。

高度

状态栏高度可以通过小程序的APi获取,而导航栏高度则需要自己去计算。这个计算需要兼容尽可能多的设备。确保不同设备都符合对应的尺寸。

在app.js中我们通过wx.getSystemInfo()方法来获取导航栏高度,和状态栏高度。并且把两个高度放在全局变量里面。方便自定义组件中调用。

 // 获取设备信息
    wx.getSystemInfo({
      success: res => {
        this.globalData.statusBarHeight = res.statusBarHeight; // 状态栏高度
         this.globalData.navbarHeight = res.system.toLowerCase().indexOf('ios') > -1 ? 44 : 48;  // 导航栏高度
      }
    })
高度

第五步

获取到了两个的高度之后就可以开始写组件了。
在navbar/index.js页面的顶部添加const app = getApp();通过getApp()来获取全局数据。
在data中赋值

  /**
   * 组件的初始数据
   */
  data: {
    statusBarHeight: app.globalData.statusBarHeight,
    navbarHeight: app.globalData.navbarHeight,
  },

然后在wxml中设置组件的高度为navbarHeight+ statusBarHeight。我的业务是让statusBarHeight透明,随系统变化,所以用的padding-top来设置,可以按照自己的业务需求来设置。
打开index.wxml页面,写页面布局和样式。

<!--components/navbar/index.wxml-->
<view class="navbar" style="padding-top:{{statusBarHeight}}px;height:{{navbarHeight}}px;line-height:{{navbarHeight}}px;background:{{background}};">
  <!-- <view></view> -->
  <!-- 首页标题 -->
  <view wx:if="{{typeBar===1}}" class="bavbar-flex">
    <!-- <view class="nav-left"></view> -->
    <view class="nav-title home-title">{{name}}</view>
    <view class="nav-right"></view>
  </view>

  <!-- 采购、值得买 -->
  <view wx:if="{{typeBar===3}}" class="bavbar-flex">
    <view class="nav-left">
      <view class="nav-left-box">
        <view class="go-back" bindtap="goHome">
          <text class="iconfont icon-shouye-"></text>
        </view>
      </view>
    </view>
    <view class="nav-title" style="width: calc(100vw - 97px);">{{name}}</view>
    <view class="nav-right"></view>
  </view>

  <!-- 返回上一页按钮和标题 -->
  <view wx:if="{{typeBar===2}}" class="bavbar-flex">
    <view class="nav-left">
      <view class="nav-left-box">
        <view class="go-back" bindtap="goBack">
          <text class="iconfont icon-back"></text>
        </view>
        <view class="line"></view>
        <view class="go-back" bindtap="goHome">
          <text class="iconfont icon-shouye-"></text>
        </view>
      </view>
    </view>
    <view class="nav-title" style="width: calc(100vw - 194px);">{{name}}</view>
    <view class="nav-right"></view>
  </view>

</view>

上面写了三种类型,每一个类型都有点击事件,我们把点击事件都写进index.js页面中,同时,还设置了几个变量,分别是name(导航标题名称)、typeBar(类型)、share(是否为分享状态)、background(背景色),这些变量由组件使用的时候动态添加,我们可以给它们先设置默认值。最后index.js完整代码如下

// components/navbar/index.js
const app = getApp();
Component({
 /**
  * 组件的属性列表
  */
 properties: {
   // 这里定义了innerText属性,属性值可以在组件使用时指定
   name: {
     type: String,
     value: '养博城',
   },
   typeBar: {
     type: Number,
     value: 1,
   },
   share: {
     type: Number,
     value: 2
   },
   background: {
     type: String,
     value: '#fff'
   }
 },

 /**
  * 组件的初始数据
  */
 data: {
   statusBarHeight: app.globalData.statusBarHeight,
   navbarHeight: app.globalData.navbarHeight,
 },

 /**
  * 组件的方法列表
  */
 methods: {
   // 返回上一页
   goBack() {
     if (this.data.share == 1) {
       wx.switchTab({
         url: '/pages/tabBar/index/index',
       })
     } else {
       wx.navigateBack()
     }
   },

  // 返回首页
   goHome() {
     wx.switchTab({
       url: '/pages/tabBar/index/index',
     })
   },
   
   // 返回首页
   goBackHome() {
     wx.switchTab({
       url: '/pages/tabBar/index/index',
     })
   },
 }
})

因为我的页面使用了第三方的图标,需要自己额外去引入,参考阿里图标

/* components/navbar/index.wxss */

/* 图标 */
@import "/assets/iconfont/iconfont";

/* 导航头 */

.navbar {
  display: flex;
  align-items: center;
  color: #141414;
}

/* 导航标题 */

.nav-title {
  flex: 1;
  font-size: 18px;
  font-family: PingFang SC;
  font-weight: bold;
  color: rgba(20, 20, 20, 1);
  opacity: 1;
  text-align: center;
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}

.home-title {
  text-align: left;
  padding-left: 40rpx;
}

/* 共有样式 */

.nav-left, .nav-right {
  /* width: 97px; */
  height: 30px;
}

/* 左边 */

.nav-left {
  padding-left: 12px;
}

.nav-left-box {
  background: rgba(255, 255, 255, 0.5);
  border: 1px solid rgba(0, 0, 0, 0.1);
  height: 30px;
  line-height: 30px;
  border-radius: 28px;
  display: flex;
  align-items: center;
  color: #000;
  width: auto;
}

.line {
  height: 19px;
  background: rgba(208, 208, 208, 1);
  opacity: 1;
  width: 1px;
}

/* 返回按钮 */

.go-back {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 0 24rpx;
}

/* 返回按钮的字体大小 */

.icon-back {
  font-size: 18px;
}

/* 回首页按钮 */

.icon-shouye {
  font-size: 18px;
}

/* 右边 */

/* .nav-right {
 
} */

/* 导航内容 类型 */

.bavbar-flex {
  width: 100vw;
  flex: 1;
  margin-right: 6rem;
  display: flex;
  align-items: center;
}

相关文章

网友评论

      本文标题:小程序自定义navBar

      本文链接:https://www.haomeiwen.com/subject/itkrzhtx.html