Vue3 + uni-app 自定义导航栏的方法封装(考虑平台兼容性)
·
JavaScript
// 抽离出来的公用方法放在utils.js文件里
const SYSTEM_INFO = uni.getSystemInfoSync()
// 导出获取的状态栏高度
export const getStatusBarHeight = ()=> SYSTEM_INFO.statusBarHeight||0 //状态栏高度 0:防止搜索引擎没有状态栏高度无法获取
//导出获取的导航栏高度
export const getTitleBarHeight = ()=> {
// 如果有胶囊按钮就执行以下逻辑 (搜索引擎没有胶囊按钮防止报错)
if (uni.getMenuButtonBoundingClientRect){
let {top,height} = uni.getMenuButtonBoundingClientRect()//胶囊按钮顶部距屏幕顶部距离,胶囊按钮本身高度
return height +(top-getStatusBarHeight())*2//导航栏高度 = 胶囊高度 + (胶囊top - 状态栏高度) × 2
}else{
return 40;//如果没有胶囊按钮就返回一个默认高度
}
}
vue
<template>
<view class="layout">
<view class="navbar">
<view class="statusBar" :style="{height:getStatusBarHeight()+'px'}"></view>
<view class="titleBar" :style="{height:getTitleBarHeight()+'px'}">
</view>
</view>
<!-- 因为状态栏+导航栏的高度是fixed 固定在头部的,虽然不会在文档流里“占位置”。 但可能会压住下面的轮播图 所以得用一个盒子填充 -->
<!-- 填充的盒子的高度=状态栏的高度+导航栏的高度 -->
<view class="fill" :style="{height:getStatusBarHeight()+getTitleBarHeight()+'px'}">
</view>
</view>
</template>
<script setup>
import {getStatusBarHeight,getTitleBarHeight} from '@/utils/system.js'
import {ref} from 'vue'
</script>
<style lang="scss" scoped>
.layout{
.navbar{
position: fixed;
top:0;
left:0;
width: 100%;
// 定义层级 防止被状态栏下方的元素被状态栏遮挡
z-index: 10;
/* 渐变背景色 */
background:
linear-gradient(to bottom,transparent,#fff 400rpx),
linear-gradient(to right,#beecd8,#F4E2D8);
.statusBar{
// border:1px solid red;
}
.titleBar{
display: flex;
align-items: center;
padding: 0 30rpx;
}
}
.fill{
}
}
</style>
整体流程如下:
-
获取状态栏高度:通过
uni.getSystemInfoSync()获取状态栏高度(statusBarHeight),并兼容处理获取失败的情况(返回 0)。 -
获取导航栏高度:通过
uni.getMenuButtonBoundingClientRect()获取胶囊按钮的位置信息(top和height),然后计算出导航栏高度。 -
填充占位:在模板中添加一个填充盒子,其高度为状态栏高度 + 导航栏高度,防止内容被固定定位的导航栏遮挡。
-
响应式样式绑定:通过
:style动态绑定样式,确保在不同设备上都能正确显示。
素材来源于B站的咸虾米老师视频,再加上自己的一点理解,老师讲的非常好,非常通俗易懂,推荐。
更多推荐


所有评论(0)