都2023了,自定义顶部导航应该不是什么新鲜事了,这里只是简单记录下
微信自己也提供了自定义顶部导航navigation-bar,大概看了下,可配置的也不少,所以看需求了,如果简单可以采用微信提供的,老规矩,先看效果
1、补充几个前置知识
- 状态栏高度(getSystemInfoSync),就是手机顶部网络那块的高度
- 胶囊位置信息(getMenuButtonBoundingClientRect),右边那个像胶囊一样的东西,通过它我们可以知道高度,计算出右边的padding
综上可知,整导航栏的高度其实是 1 所在区域 = 状态栏高度 + 胶囊高度 + ( 胶囊距离顶部 - 状态栏高度 ) * 2
因为,胶囊和状态栏之间还有一定间隙,所以完整的高度需要 胶囊距离顶部 - 状态栏高度
2、实现
首先需要知道上面说的那几个位置信息,思路分析
- 通常这些信息在小程序启动的时候获取一次就行了,所以我们需要做两手准备,如果全局里面没有,则导航组件再自己获取一次
- 如果没有获取到,应该有默认值(这时候样式肯定有不好看,不过没办法~)
- 顶部一般是定位固定的,所以用了导航组件后,应该有一个盒子用于占位补充定位导致塌陷的高度
3、完整代码如下
js如下
// component/navBar/navBar.js
const app = getApp()
Component({
/**
* 组件的属性列表
*/
properties: {
// 标题
title: {
type: String,
value: ''
},
// 是否需要返回
hasBack: {
type: Boolean,
value: false
},
// 背景色
bgc: {
type: String,
value: 'linear-gradient(to top, #96fbc4 0%, #f9f586 100%)'
},
// 是否固定
isFixed: {
type: Boolean,
value: true
}
},
/**
* 组件的初始数据
*/
data: {
navInfo: {
paddingLeft: 0,
paddingTop: 0,
navHeight: 0
},
},
/**
* 生命周期钩子
* **/
lifetimes: {
created() {
const { getSystemInfoSync, menuInfo} = app.globalData
if(!Object.keys(getSystemInfoSync).length || !Object.keys(menuInfo).length) {
console.warn('没有胶囊位置信息,重新获取中')
this.customNavBarInfo()
}
},
attached() {
// 计算导航高度信息
this.getNavBarInfo()
}
},
/**
* 组件的方法列表
*/
methods: {
/**
* 计算导航高度信息
* **/
getNavBarInfo() {
// 防止没有获取到位置信息
let navInfo = {
paddingLeft: 7, // 默认胶囊距离屏幕右边的距离
paddingTop: 20,// 默认
navHeight: 44 // 默认导航栏高度
}
if(Object.keys(app.globalData.menuInfo).length && Object.keys(app.globalData.getSystemInfoSync).length) {
const { top,height,right,width } = app.globalData.menuInfo
const { statusBarHeight,windowWidth } = app.globalData.getSystemInfoSync
navInfo = {
paddingLeft: windowWidth - right,
paddingTop: statusBarHeight,
navHeight: height + ( top - statusBarHeight ) * 2,
menuWidth: width
}
}
this.setData({
navInfo
})
},
/**
* 获取胶囊位置信息
* **/
customNavBarInfo() {
app.globalData.menuInfo = wx.getMenuButtonBoundingClientRect()
app.globalData.getSystemInfoSync = wx.getSystemInfoSync()
},
}
})
css如下
.nav{
display: flex;
align-items: center;
}
// 这是笔者写一个宽度,需要根据自己情况调整
.left{
width: 80rpx;
}
.custom-nav{
z-index: 999;
top: 0;
right: 0;
left: 0;
}
通常在app.js里面提前获取一次
App({
onLaunch() {
this.globalData.menuInfo = wx.getMenuButtonBoundingClientRect() || {}
this.globalData.getSystemInfoSync = wx.getSystemInfoSync() || {}
},
globalData: {
// 完整胶囊信息
menuInfo: {},
// 完整系统信息
getSystemInfoSync: {},
}
})