组件效果展示:
解决的问题:
1. 使用uni.getSystemInfoSync获取到当前手机的状态栏区域的高度和手机型号
2. 通过获取到的手机型号来判断,如果是ios就+40px,否则就+44px
3. 导航栏高度 = 手机状态栏高度 + 40(ios)或44(安卓)
4. 导航栏组件, 外层一个 view 充当导航栏, 里面嵌套一个 view 用来充当 naviBar, 将动态获取的状态栏高度赋给外层的 padding-top
5. 通过延迟500毫秒解决 IOS 真机无法第一时间获取状态栏高度的问题
6. 原本想考虑给自定义导航添加插槽,增加组件灵活性,实际发现并不实用
7. 该组件刚开始使用默认高度 88px, 然后在根据获取的数据动态调整,解决组件展示时闪屏问题
该组件满足导航的基本使用
自定义组件:
<!--
使用示例:
1.右item显示新增 (默认)
<kNavBar name='这是标题' @goBack="goBack" @goAdd="goAdd" >
2.右item 显示文字
<kNavBar name='这是标题' rightText="按钮" @goBack="goBack" @goText="goText" >
3.右item为空
<kNavBar name='这是标题' rightText=" " @goBack="goBack" >
-->
<template>
<view>
<view class="topNav" :style="{paddingTop: (statusBarHeight || 44) + 'px'}">
<view class="naviBar" :style="{ height : (navBarHeight || 44) + 'px'}">
<!-- 返回按钮 -->
<image class="nav-left" src="../static/fanhui.png" v-if="isBack" mode="aspectFit" @tap="goBack"></image>
<!-- 标题 -->
<view class=" navi-title">{{name}}</view>
<!-- 右边新增按钮 -->
<view class="nav-right" v-if="rightText.length > 0" @tap="goText">{{rightText}}</view>
<image class="nav-right-img" v-else src="../static/add.png" mode="" @tap="goAdd"></image>
</view>
</view>
<!-- 空白块, 填补空缺 -->
<view class="" :style="{height : (navHeight || 88) + 'px'} "></view>
</view>
</template>
<script>
export default {
props: {
// 返回按钮是否隐藏
isBack: {
type: Boolean,
default () {
return true
}
},
// 标题
name: {
type: String,
default () {
return ''
}
},
// 右边按钮的文字
rightText: {
type: String,
default () {
return ''
}
}
},
data() {
return {
statusBarHeight: 0, // 状态栏的高度
navBarHeight: 0, // 导航条的高度
navHeight: 0, // 导航栏高度
};
},
created() {
const that = this
setTimeout(() => {
let {
statusBarHeight,
system
} = uni.getSystemInfoSync()
// 网页调试时, statusBarHeight 若为 0 ,则给一个默认高度
that.statusBarHeight = statusBarHeight > 0 ? statusBarHeight : 44
// 导航条的高度 = iOS 40px / 安卓 44px
that.navBarHeight = (system.indexOf("iOS") > -1 ? 40 : 44)
// 导航栏的高度 = 手机状态栏高度 + 40px(IOS) / 44px(安卓)
that.navHeight = that.statusBarHeight + that.navBarHeight
}, 500); // 延迟500毫秒再尝试获取
},
methods: {
// 返回事件
goBack() {
this.$emit('goBack')
},
// 新增事件
goAdd() {
this.$emit('goAdd')
},
// 文字事件
goText() {
this.$emit('goText')
},
}
}
</script>
<style scoped>
.topNav {
/* background-color: #00aa7f; */
/* 背景图片 */
background-image: url('@/static/bgimg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
/* 定位 */
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
}
.naviBar {
position: relative;
display: flex;
/* 侧轴布局 */
align-items: center;
/* 主轴布局 */
justify-content: flex-start;
padding: 0 20rpx;
box-sizing: border-box;
}
.navi-title {
width: 70%;
font-size: 17px;
color: #fff;
/* 居中 */
text-align: center;
margin: 0 auto;
/* background-color: pink; */
}
.nav-left {
width: 40rpx;
Height: 40 rpx;
padding-right: 50rpx;
position: absolute;
left: 20rpx;
/* background-color: orange; */
}
.nav-right-img {
width: 40rpx;
Height: 40 rpx;
position: absolute;
right: 25rpx;
/* background-color: orange; */
}
.nav-right {
font-size: 15px;
color: #fff;
position: absolute;
right: 25rpx;
/* background-color: orange; */
}
</style>