首先来看下导航栏结构,红色框叫状态栏,小程序和APP有,h5则没有,蓝色部件叫导航栏,绿色部分叫胶囊按钮,只有小程序有。
修改配置
由于我们所有页面都使用自定义导航栏,所以直接在pages.json里改全局配置,navigationStyle改成custom就能使用自定义导航栏,否则会出默认导航栏,如果只想改某个页面,可以在pages的style里面设置
"globalStyle": {
"navigationStyle":"custom" //使用自定义导航栏
},
新建navbar组件
在components文件夹下新建组件并创建同名目录,叫navbar/navbar.vue,这种components/组件名/组件名.vue的命名规则叫easyCom,然后父组件使用该子组件的时候不需要导入,可以直接使用。
<template>
<view class="navbar">
<view class="navbar-fixed">
<!-- 状态栏 -->
<view :style="{height:statusBarHeight + 'px'}"></view>
<view class="navbar-content" :style="{height:navBarHeight+'px',width:windowWidth+'px'}">
<view class="navbar-search">
<view class="navbar-search_icon">
<uni-icons type="search" size="16" color="#999"></uni-icons>
</view>
<view class="navbar-search_text">热门新闻</view>
</view>
</view>
</view>
<view :style="{height: statusBarHeight+navBarHeight+'px'}"></view>
</view>
</template>
<script>
export default {
data() {
return {
statusBarHeight: 20,
navBarHeight: 45,
windowWidth: 375
};
},
created() {
//获取手机系统信息
const info = uni.getSystemInfoSync();
//设置状态栏高度
this.statusBarHeight = info.statusBarHeight;
this.windowWidth = info.windowWidth;
// h5 app mp-alipay没有胶囊按钮
// #ifndef H5 || APP-PLUS || MP-ALIPAY
// 获取胶囊的位置
const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
// (胶囊底部高度 - 状态栏的高度) + (胶囊顶部高度 - 状态栏内的高度) = 导航栏的高度
this.navBarHeight = (menuButtonInfo.bottom - info.statusBarHeight) + (menuButtonInfo.top - info
.statusBarHeight)
this.windowWidth = menuButtonInfo.left
// #endif
},
methods: {}
}
</script>
<style lang="scss" scoped>
.navbar {
.navbar-fixed {
position: fixed;
top: 0;
left: 0;
z-index: 99;
width: 100%;
background-color: $mk-base-color;
.navbar-content {
padding: 0 15px;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
height: 45px;
.navbar-search {
display: flex;
align-items: center;
padding: 0 10px;
width: 100%;
height: 30px;
border-radius: 30px;
background-color: #fff;
.navbar-search_icon {
margin-right: 10px;
}
.navbar-search_text {
width: 100%;
font-size: 14px;
color: #999;
}
}
}
}
}
</style>
代码解析
由于导航栏要固定在屏幕最上方,所以需要使用position: fixed,但使用fixed后内容会往上,所以还需要一个占位view,这就是<view :style="{height: statusBarHeight+navBarHeight+'px'}"></view>的作用,接下来的关键是如何获取到状态栏高度和导航栏高度。
状态栏的话通过uni.getSystemInfoSync();就能拿到,h5和app的导航栏根据设计图来就行了,小程序比较特殊,他的导航栏是固定的,还有一个胶囊按钮,所以需要计算。计算公式是(胶囊底部高度 - 状态栏的高度) + (胶囊顶部高度 - 状态栏内的高度) = 导航栏的高度
而导航栏的宽度就是menuButtonInfo.left