微信小程序自定义头部导航nav

Posted 优小U

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信小程序自定义头部导航nav相关的知识,希望对你有一定的参考价值。

1.封装自定义nav导航组件

// app.js
App(
  globalData: 
    systeminfo: false,   //系统信息
    headerBtnPosi: false  //头部菜单高度
  
)
// components/nav/nav.js
const app = getApp();
Component(
  properties: 
    vTitle:  // 标题
      type: String,
      value: ""
    ,
    isSearch: 
      type: Boolean,
      value: false
    ,
    noBorder:   // 不需要下边框
      type: Boolean,
      value: false
    ,
    color:  // 标题颜色
      type: String,
      value: "black"
    ,
    bg:  // 背景图片路径
      type: String,
      value: ""
    ,
    showBack:   // 显示返回按钮
      type: Boolean,
      value: true
    
  ,
  data: 
    haveBack: true, // 是否有返回按钮
    statusBarHeight: 0, // 状态栏高度
    navbarHeight: 0, // 顶部导航栏高度
    navbarBtn:  // 胶囊位置信息
      height: 0,
      width: 0,
      top: 0,
      bottom: 0,
      right: 0
    ,
    cusnavH: 0 //title高度
  ,
  // 微信7.0.0支持wx.getMenuButtonBoundingClientRect()获得胶囊按钮高度
  attached: function () 
    if (!app.globalData.systeminfo) 
      app.globalData.systeminfo = wx.getSystemInfoSync()
    
    if (!app.globalData.headerBtnPosi)
      app.globalData.headerBtnPosi = wx.getMenuButtonBoundingClientRect()
    let statusBarHeight = app.globalData.systeminfo.statusBarHeight // 状态栏高度
    let headerPosi = app.globalData.headerBtnPosi // 胶囊位置信息
    let btnPosi = 
      // 胶囊实际位置,坐标信息不是左上角原点
      height: headerPosi.height,
      width: headerPosi.width,
      top: headerPosi.top - statusBarHeight, // 胶囊top - 状态栏高度
      bottom: headerPosi.bottom - headerPosi.height - statusBarHeight, // 胶囊bottom - 胶囊height - 状态栏height (胶囊实际bottom 为距离导航栏底部的长度)
      right: app.globalData.systeminfo.windowWidth - headerPosi.right // 这里不能获取 屏幕宽度,PC端打开小程序会有BUG,要获取窗口高度 - 胶囊right
    
    let haveBack
    if (this.properties.showBack === false) 
      haveBack = false
     else 
      haveBack = true
    
    
    var cusnavH = btnPosi.height + btnPosi.top + btnPosi.bottom // 导航高度
    this.setData(
      haveBack: haveBack, // 获取是否是通过分享进入的小程序
      statusBarHeight: statusBarHeight,
      navbarHeight: headerPosi.bottom + btnPosi.bottom, // 胶囊bottom + 胶囊实际bottom
      navbarBtn: btnPosi,
      cusnavH: cusnavH
    )
    //将实际nav高度传给父类页面
    this.triggerEvent("commonNavAttr", 
      height: headerPosi.bottom + btnPosi.bottom
    )
  ,
  methods: 
    _goBack: function () 
      wx.navigateBack(
        delta: 1
      )
    ,
    bindKeyInput: function (e) 
      // console.log(e.detail.value);
    
  
)
// components/nav/nav.json

  "component": true,
  "usingComponents": ,
  "navigationStyle": "custom"

<!-- components/nav/nav.wxml -->
<view class="custom_nav" style="height:navbarHeightpx;position: relative;">
  <image wx:if=" !!bg " class="head-bg" mode="widthFix" src="bg"></image>
  <view class="custom_nav_box noBorder?'no-border':''" style="height:navbarHeightpx;">
    <view class="custom_nav_bar" style="top:statusBarHeightpx; height:cusnavHpx;">
      <block wx:if="isSearch">
        <input class="navSearch" style="height:navbarBtn.height-2px;line-height:navbarBtn.height-4px; top:navbarBtn.top+1px; left:navbarBtn.rightpx; border-radius:navbarBtn.height/2px;" maxlength="10" bindinput="bindKeyInput" placeholder="输入文字搜索"/>
      </block>
      <block wx:else>
        <view class="custom_nav_icon" style="height:navbarBtn.heightpx;line-height:navbarBtn.height-2px; top:navbarBtn.toppx; left:navbarBtn.rightpx;">
          <view wx:if="haveBack" class="icon-back" bindtap='_goBack'>
            <!-- <image src='/res/images/back.png' class='back-pre'></image> -->
            <iconfont name="back" color="#ff6200" size="44"/>
          </view>
        </view>
        <view class="nav_title" style="color: color;height:cusnavHpx; line-height:cusnavHpx;">
          vTitle
        </view>
      </block>
    </view>
  </view>
</view>
/* components/nav/nav.wxss*/
.custom_nav 
  width: 100%;
  position: relative;


.head-bg 
  position: fixed;
  top: 0;
  left: 0;
  z-index: -1;
  width: 100%;

.custom_nav_box 
  position: fixed;
  width: 100%;
  z-index: 99999;
  border-bottom: 1rpx solid rgba(255, 255, 255, 0.3);
  box-shadow: 2rpx 2rpx 12rpx 0rpx rgba(95,95,95,0.1);

.custom_nav_box.no-border 
  border-bottom: none;
  box-shadow: none;


.custom_nav_bar 
  position: relative;
  z-index: 9;


.custom_nav_box .nav_title 
  font-size: 30rpx;
  text-align: center;
  position: absolute;
  max-width: 360rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  z-index: 1;


.custom_nav_box .custom_nav_icon 
  position:absolute;
  z-index: 2;
  display: inline-block;
  border-radius: 50%;
  vertical-align: top;
  font-size:0;
  box-sizing: border-box;

.custom_nav_box .custom_nav_icon.borderLine 
  border: 1rpx solid rgba(255, 255, 255, 0.3);
  background: rgba(0, 0, 0, 0.1);


.navbar-v-line 
  width: 1px;
  margin-top: 14rpx;
  height: 32rpx;
  background-color: rgba(255, 255, 255, 0.3);
  display: inline-block;
  vertical-align: top;


.icon-back 
  display: flex;
  align-items: center;
  width: 74rpx; 
  padding-left: 20rpx;
  height: 100%;


.icon-home 
  display: inline-block;
  width: 80rpx;
  text-align: center;
  vertical-align: top;
  height: 100%;


.icon-home .home_a 
  height: 100%;
  display: inline-block;
  vertical-align: top;
  width: 35rpx;


.custom_nav_box .back-pre,
.custom_nav_box .back-home 
  width: 40rpx;
  height: 40rpx;


.navSearch 
  width: 200px;
  background: #fff;
  font-size: 14px;
  position: absolute;
  padding: 0 20rpx;
  z-index: 9;

2.修改全局配置

navigationStyle 字段设置为 custom,这样就能使用自定义的nav。

// app.json
"window": 
  "backgroundTextStyle": "light",
  "navigationBarBackgroundColor": "#fff",
  "navigationBarTitleText": "测试",
  "navigationBarTextStyle": "black",
  "navigationStyle": "custom"
,

3.页面使用

需要使用自定义nav的页面,需要每个页面都要引入自定义组件:

// pages/service/service.json

  "usingComponents": 
    "nav-component": "/components/nav/nav"
  

<!-- pages/service/service.wxml -->
<nav-component v-title="服务" showBack=" false "></nav-component>

效果:

显示返回按钮,具体样式可以在自定义组件中定义默认样式:

<nav-component v-title="订单详情"></nav-component>


复杂一点的头部带背景图片:

<nav-component 
  v-title="首页" 
  color="white" 
  bg="/res/images/home_bg.png"
  no-border=" true "
  showBack="false"
></nav-component>

以上是关于微信小程序自定义头部导航nav的主要内容,如果未能解决你的问题,请参考以下文章

如何实现全屏小程序及自定义左上角胶囊

总结-微信小程序自定义顶部导航(超详细)附加效果图

微信小程序 自定义导航栏

微信小程序自定义 顶部nav 和 底部tabbar

微信小程序自定义 顶部nav 和 底部tabbar

微信小程序自定义 顶部nav 和 底部tabbar