先说结论:
别折腾了,直接用uni 的轮子就行,二开也可以,我这个方法能实现,但是安卓机总会有获取不到胶囊高度的情况,偶现。。
1、背景:
最近使用uni-app开发多端使用的小程序(微信、支付宝、H5), 开发过程中需要做一个nav组件
最先想到的肯定是用别人造好的轮子,比如uni-nav-bar这个组件,但是实测使用发现,不同手机型号
(ios/安卓)都会有一些兼容问题,而且使用也会有一些限制,不够舒服,所以就想办法自己做了个简单的
header , 这里写一下思路,思路有了,其他的按需求开发即可
🍕首先大概解释一下nav的基本内容
nav的高度一般是通过getSystemInfo获取系统信息,得到titleBarHeight和statusBarHeight,然后相加得到最终高度 , 但是这种方式会有一些兼容问题,后续会细说
DEMO:
uni.getSystemInfo(() => {
const systemInfo = app.globalData.systemInfo;
this.systemInfo = systemInfo;
/**
*@statusBarHeight: 一般为25px
*@titleBarHeight :一般为44px
*/
// #ifdef MP-ALIPAY
this.barHeight = systemInfo.titleBarHeight + systemInfo.statusBarHeight || 69;
this.searchHeight = systemInfo.titleBarHeight || 44;
// #endif
// #ifdef MP-WEIXIN
this.barHeight = systemInfo.safeArea.top + systemInfo.statusBarHeight || 69;
this.searchHeight = systemInfo.statusBarHeight || 44;
// #endif
});
2、需求:
如下图 , 内容区域不管在什么设备下都要和胶囊按钮 同高 或在一条基线上,至少不能有很明显的偏差。。。
3、遇到的问题:
首先说明一下,这里我就大概看了一下,没有深入研究该组件,可能是我用法不对的原因
使用uni-nav-bar过程遇到的几个问题:
1、左侧位置较小(如图圈起来的部分)
-
这个比较小,可以改源码样式处理
2、statusBar不同机型高度差很多,有的机型干脆获取不到
最终造成内容区域和胶囊按钮位置偏差 ,如图:
-
正常情况
-
(nexus、安卓机器等)
4、实现思路:
1、获取右侧胶囊的位置信息,把内容区域的高度调整到和胶囊按钮同样的位置即可
2、状态栏高度则BFC布局高度自适应,不再设置固定高度
3、胶囊下面填充区域直接写死,我这边固定10px , 按需设置即可
5、具体实现:
5.1. 获取胶囊按钮高度位置 , 并设置nav的高度
✨✨✨✨最重要的步骤✨✨✨✨🐱👤🐱👤🐱👤🐱👤🐱👤🐱👤🐱👤
getNavHeight() {
// #ifndef H5
const res = wx.getMenuButtonBoundingClientRect();
const statusHeight = res?.top || 0; //胶囊距离顶部
const navHeight = res.height; //胶囊高度
this.statusBarHeight = statusHeight;
this.navHeight = navHeight + statusHeight + 10; //加10是因为样式需要,后续做内边距
// #endif
// #ifdef H5
this.statusBarHeight = 14;
this.navHeight = 44;
// #endif
}
5.2. 布局大概如下
5.3. html布局
这里只是做一个演示,实际最终要按需求来写
<view class="nav_header" :style="{ height: navHeight + 'px' }">
<!-- 状态栏 -->
<view class="status-bar"/>
<!-- 内容区域 -->
<view class="content">
<!-- logo -->
<image class="nav_icon" src="@/static/test-logo.png" mode="aspectFit" />
<!-- 跳转按钮 -->
<navigator
class="search_link"
open-type="navigate"
url="/pages/search/index?source=首页"
hover-class="none"
>
<image class="search_icon" src="@/static/images/search.png" mode="aspectFit" />
搜索
</navigator>
</view>
</view>
5.4. 样式处理
布局及需求如下
- nav_header
- status_bar(高度自适应,自动填满剩下区域)
- content (高度固定 or 和胶囊按钮在同一条线 )
其实上面算一个比较经典的bfc,常见的bfc左侧宽度固定,右侧自适应,而这里换成了下面的内容区域高度固定,顶部状态栏高度自适应😅
.nav_header {
position: fixed;
width: 100%;
top: 0;
left: 0;
z-index: 10;
overflow: hidden;
height: auto;
display: flex;
flex-direction: column;
align-items: flex-start;
box-sizing: border-box;
background-color: green;
/* #ifndef H5*/
padding-bottom: 10px;
/* #endif*/
/* #ifdef H5*/
padding-bottom: 8px;
/* #endif*/
.status-bar {
width: 100%;
flex: 1;
background-color: cornflowerblue;
}
.content {
display: flex;
background: #ff602a;
width: 100%;
height: 50rpx;
z-index: 10;
.nav_icon {
color: #fff;
width: 204rpx;
height: 100%;
}
.search_link {
margin-left: 20rpx;
box-sizing: border-box;
height: 100%;
align-items: center;
border-radius: 32rpx;
background: rgba(255, 255, 255, 0.56);
color: #ffffff;
padding: 0 20rpx;
margin-left: 60rpx;
width: 300rpx;
.search_icon {
width: 36rpx;
height: 36rpx;
margin-right: 16rpx;
}
}
}
}
6、效果
6.1.微信 :
6.2.支付宝:
7、最终效果:
经真机测试,这种方法做出来的nav不管是安卓还是ios兼容都还是蛮ok的,也确实能解决我碰到的问题,
当然这里只是做了一个非常简单的header ,如果需要的话可以封装成通用header,类似uni-nav-bar一样通过slot的方式自定义header
-
微信开发者工具
-
支付宝开发者工具
写在最后😬🤯😬🧐🤓:
这里只是提供一个解决思路,如果大家有更好的方法或者好用的轮子,请务必留在评论区,谁都别拦着我要跪着学🤩🤩!