微信小程序自定义导航栏_java



A

单页自定义导航栏


使用到的主要 Api


wx.getSystemInfoSync() //获取系统信息  statusBarHeight:手机状态栏的高度,单位:px;wx.getMenuButtonBoundingClientRect() // 获取胶囊按钮的信息  top:距离上边界的距离,单位:px;  right:距离右边界的距离,单位:px;  height:胶囊的高度,单位:px;

计算导航栏的高度


const systemInfo = wx.getSystemInfoSync(); //获取系统信息const menuInfo = wx.getMenuButtonBoundingClientRect(); // 获取胶囊按钮的信息this.globalData.menuHeight = menuInfo.height; // 获取胶囊按钮的高this.globalData.statusBarHeight = systemInfo.statusBarHeight; // 获取状态栏的高this.globalData.menuRight = menuInfo.right; // 获取胶囊按钮的距离屏幕最右边的距离(此处用于设置导航栏左侧距离屏幕的距离)this.globalData.navBarHeight = (menuInfo.top - systemInfo.statusBarHeight) * 2 + menuInfo.height; // 计算出导航栏的高度

考虑到这个信息可能需要多个页面使用到,我将这段计算的代码放到了微信小程序入口的文件app.js


//小程序初始化完成时触发,全局只触发一次  onLaunch: function () {    // 上面的代码放到这里      },  globalData: {    navBarHeight:0,// 导航栏高度    menuHeight:0,//胶囊按钮 高度    statusBarHeight:0,//状态栏高度    menuRight:0,//胶囊按钮 距离屏幕右边的距离  },


微信小程序自定义导航栏_java_02


微信小程序自定义导航栏_java_03


这里只是首页 pages/views/home/home 需要用到

在单页的 home.json 文件里


"usingComponents": {    "navbar":"../../components/navBar/navBar"    ...},"navigationStyle": "custom"

这里我使用了一个微信组件 navBar 来实现导航栏布局

在单页里只需引入组件 navBar,并且将必要的参数传递给组件就可以了,这样不用增加单页面的代码,如果多页面使用可以做一定的适配。

home.wxml


  

home.js


const App = getApp();Page({  data: {    navigationSetting:{      title:'XXXXXXX',      height: App.globalData.navBarHeight,      paddingTop: App.globalData.statusBarHeight,      backgroundColor:'#fff',      size:'default',      noticeNum: 0,    },      },  ...  })


下面是自定义组件的代码实现

navBar.wxml


                  {{defaultSetting.noticeNum}}            {{defaultSetting.title}}

navBar.js


const App = getApp();Component({  //接收 外部传入到属性值  properties:{    defaultSetting:{      type:Object,      value:{        title:'默认标题',        height:20,        paddingTop:0,        backgroundColor:'#fff',        size:'default',        noticeNum: 0      }    },  },  // 定义响应式数据  data:{    staticImgUrl: App.url.FARM_APPLET_STATIC,  },  // 定义方法  methods:{    bindCallEvent(){      App.href({        key: '/pages/views/notice/noticelist'      });    }  }})

navBar.wxss


image{    display: block;    width: 100%;    height: 100%;}
.navigationPage {    position: fixed;    top: 0;    left: 0;    z-index: 9999999;    width: 100%;    background-color: red;    display: flex;    align-items: center;    text-align: center;    box-sizing: content-box;}
.navigationIcon {    position: absolute;    left: 30rpx;}
.navigationIcon .notice{    padding-top: 10rpx;    width: 40rpx;    height: 40rpx;    position: relative;    top: 0;    left: 0;}
.navigationIcon .notice .notice-circle{    position: absolute;    top: -4rpx;    right: -18rpx;    width: 30rpx;    height: 30rpx;    border-radius: 50%;    background: #FA6400;    font-size: 20rpx;    text-align: center;    line-height: 30rpx;    color: #ffffff;    border: 1px solid #ffffff;}
.navigationTitle {    font-weight: 400;    flex: 1;}
.small {    font-size: 14px;}
.default {    font-size: 16px;}
.large {    font-size: 18px;}

navBar.json


{  "component": true,  "usingComponents": {}}




B

全局页面导航栏


对于单页面导航栏的 标题title 变量和组件内的布局动态变动,这点还是比较容易实现的。

这里主要说一下对于返回按钮的事件实现


getCurrentPages() // 获取当前页面栈。数组中第一个元素为首页,最后一个元素为当前页面。


返回上一页事件


// 返回上一页面  _navback() {    let _pageLength = getCurrentPages().length;    if (_pageLength > 1) {      App.href({        type:'navigateBack',        data:{delta:1}      });  // 我自己封装的方法,就是返回上一页的意思。    }  },

如果有 home【返回首页】按钮,那就需要先拿到当前页面,通过与首页比对,判断是否已经是首页,再做跳转操作。


const App = getApp()Component({  ...  attached: function () {    let _pages = getCurrentPages();    let _num = _pages.length - 1;    let _cur = _pages[_num].route.split('/')[2];    console.log(_cur,_pages.length)    // 定义导航栏的高度   方便对齐    this.setData({      cur: _cur,    });  },  methods: {    //返回到首页    _backhome() {      let _cur = this.data.cur;      if (_cur == 'home') return; // 这里我的首页是 pages/views/home/home      wx.reLaunch({        url: '/pages/views/home/home',      })    },    }})