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,//胶囊按钮 距离屏幕右边的距离 },
这里只是首页 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', }) }, }})