基于原生小程序的自定义头部导航

项目需求,好多页面要自定义导航,样式还五花八门,肿么办?那就弄个头部导航组件吧! 先上效果图

image.png

下面一组是透明和不透明切换的效果

image.png

image.png

首先,生成原生小程序四大天王

image.png

然后,我们在wxml中写页面结构,我们这里利用slot插槽,来支持导航内容的自定义填充

<!-- 自定义导航 -->
<!-- isShadow 导航是否有阴影  navBar 导航栏高度  statusBar 状态栏高度-->
<!-- bgTransparent 导航是否透明 bgColor 导航背景色  statusBar 状态栏高度-->
<view
    class="customer_header {{isShadow ? 'shadow':''}}"
    style="height:{{navBar+statusBar}}px;background: {{bgTransparent ? bgColor : 'transparent'}};padding-bottom: 6px;"
>
  <view
      class="hader_box flex_jus_start
      style="margin-top: {{statusBar}}px;height:{{navBar}}px;"
  >
    <slot></slot>
  </view>
</view>
<!-- 因为是自定义导航,所以用的fixed定位,需要一个占位符将定位的空白区域填充 -->
<view class="standing_block" style="height:{{navBar+statusBar}}px;"></view>

接下来写wxss

.flex_jus_start{
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
}
.standing_block{
  width: 100%;
  background: transparent;
}
.customer_header{
  position: fixed;
  left: 0;
  right: 0;
  top:0;
  width: 100%;
  height: 74rpx;
  margin: auto;
  z-index: 99;
}
.customer_header .hader_box{
  padding-left: 12rpx;
}
.customer_header .no_padding{
  padding-left: 0rpx;
}
.shadow{
  box-shadow: 0 4rpx 8rpx 0 rgba(0,0,0,0.08);
}

样式根据你们自己的需要去更改,接下来我们写js文件

const app = getApp()
Component({
  options: {
    multipleSlots: true // 在组件定义时的选项中启用多slot支持
  },
  properties: {
    bgTransparent:{
      type:Boolean,
      value:false
    },//是否导航背景透明
    bgColor:{
      type:String,
      value:'#fff'
    },//导航背景色
    isShadow:{
      type:Boolean,
      value:false
    },//是否带底部阴影
  },
  data: {
    navBar:0,//导航栏高度
    statusBar:0,//状态栏高度
  },
  attached: function () {
    //通过微信提供的 wx.getSystemInfo()方法,拿到状态栏高度和导航栏高度
    wx.getSystemInfo({
      success: res => {
        // 状态栏高度
        let statusBarHeight = res.statusBarHeight;
        let menuButtonRect = wx.getMenuButtonBoundingClientRect()
        // 导航栏高度
        let navigationBarHeight = (menuButtonRect.top - statusBarHeight) * 2 + menuButtonRect.height;
        this.setData({
          navBar:navigationBarHeight,
          statusBar:statusBarHeight
        })
      }
    });
  }
})

这样,一个最基本的自定义头部导航组件就写完了,我们来看一下如何使用;
在json文件中,我们先引入组件

{
  "usingComponents": {
    "coustom-nav":"/components/coustom-nav/index"
  },
  "navigationStyle": "custom"
}

然后页面使用

<view class="custom_nav">
  <coustom-nav bgTransparent="{{bgTransparent}}">
    <!-- 自定义导航插槽中的内容 我们在组件中已经进行了flex布局,这你直接写内容和具体样式就好了-->
    <view class="shop_image" bindtap="showShop">
      <image src="{{shop_avatar}}" mode="aspectFill"></image>
    </view>
    <view class="shop_name">「{{shop_name}} 」的职场店铺</view>
  </coustom-nav>
</view>

假如你想根据页面滑动来进行导航的透明与不透明显示,只需要在应用的页面这样写就可以了

//页面滑动,导航背景变化
  onPageScroll(e){
    //创建节点选择器
    let query = wx.createSelectorQuery();
    //选择id
    let that = this; 
    query.select('.custom_nav').boundingClientRect(function(rect) {
      if (e.scrollTop > rect.height) { // 页面上卷高度大于导航高度时
        that.setData({
          bgTransparent: true //导航头部颜色变为白色
        })
      } else {
        that.setData({
          bgTransparent: false  // 导航头部颜色变为透明
        })
      }
    }).exec();
  }

这样,一个自定义导航就完成了,你也可以在此基础上进行二次封装,制定更多的属性,满足你的业务需求

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

推荐阅读更多精彩内容