uniapp 包自定义导航栏和导航栏适配(顶部固定内容滚动布局)
最编程
2024-03-30 16:48:02
...
一、思路解析
- 1、在
pages.json
的"style"
中通过"navigationStyle": "custom"
属性设置自定义导航
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"navigationStyle": "custom"
}
},
- 2、封装自定义导航栏组件,通过父子传值控制
背景色
、回退图标
、标题
等内容 - 3、计算并设置
胶囊信息
、状态栏信息
、导航栏总高度
等 - 4、页面引入并使用
注意:示例封装组件的标题图标均在左侧,具体可根据业务逻辑自行修改即可
二、组件代码注释详解
<template>
<view class="nav-box" @click="getHeadHeight" :style="{'height':height+'px','background':bgColor}">
<!-- 状态栏占位 -->
<view class="status_bar" :style="{'height':statusBarHeight+'px'}"></view>
<!-- 导航内容 -->
<view class="nav-main" :style="{'height': navBarHeight+'px'}">
<!-- 回退图标 -->
<image src="../../static/demo/leftArrow.png" mode="" class="back" @click="back(path)" v-if="backIcon">
</image>
<!-- 标题 -->
<text class="nav-main-title" :style="!backIcon?'display: block;margin-left:20rpx;':''">{{title}}</text>
<!-- 弹性盒占位 -->
<view v-if="backIcon"></view>
</view>
</view>
</template>
<script>
export default {
//接收父组件传值(仅示例,其他业务场景可自行扩展)
props: {
// 导航栏背景色相关
bgColor: {
type: String,
default: "#F5F5F5"
},
// 控制回退图标
backIcon: {
type: Boolean,
default: true
},
// 标题相关
title: {
type: String,
default: "我的"
},
// 特定路径
path: {
type: String,
}
},
data() {
return {
// 自定义导航栏高度总和
height: 0,
// 微信小程序胶囊布局位置信息
menuButtonRect: {},
// 状态栏高度
statusBarHeight: 0,
// 导航栏高度(不包含状态栏)
navBarHeight: 0
}
},
created() {
this.getHeight();
this.getHeadHeight()
},
methods: {
// 子传父 总高度
getHeadHeight() {
this.$emit('getHeadHeight', this.height)
},
//计算导航栏总高度
getHeight() {
// 判断获取微信小程序胶囊API是否可用
if (uni.canIUse('getMenuButtonBoundingClientRect')) {
// 获取状态栏高度(电量时间通知等信息-单位px)
let sysInfo = uni.getSystemInfoSync();
this.statusBarHeight = sysInfo.statusBarHeight;
// 获取微信小程序胶囊布局位置信息
let rect = uni.getMenuButtonBoundingClientRect();
this.menuButtonRect = JSON.parse(JSON.stringify(rect));
// (胶囊上部高度-状态栏高度)*2 + 胶囊高度 = 导航栏高度(不包含状态栏)
//以此保证胶囊位于中间位置,多机型适配
let navBarHeight = (rect.top - sysInfo.statusBarHeight) * 2 + rect.height;
this.navBarHeight = navBarHeight;
// 状态栏高度 + 导航栏高度 = 自定义导航栏高度总和
this.height = sysInfo.statusBarHeight + navBarHeight;
} else {
uni.showToast({
title: '您的微信版本过低,界面可能会显示不正常',
icon: 'none',
duration: 4000
});
}
},
//返回上一级
back(path) {
uni.navigateBack()
},
}
}
</script>
<style lang="scss" scoped>
.status_bar {
width: 100%;
}
.nav-main {
display: flex;
align-items: center;
// justify-content: space-between;
padding: 0 40rpx 0 20rpx;
.back {
width: 50rpx;
height: 50rpx;
margin-right: 20rpx;
}
.nav-main-title {
color: #fff;
font-size: 32rpx;
}
}
</style>
三、页面使用(顶部固定内容滚动布局)
<template>
<view class="content">
<!-- 使用自定义导航栏组件 -->
<HeadNav title="列表页" bgColor="#0a64da" @getHeadHeight="getHeadHeight" :backIcon="true"
path='/pages/index/index'></HeadNav>
<!-- 屏幕可视区域高度 - 自定义导航高度 = 滚动区域高度 -->
<scroll-view scroll-y="true" :style="'height: calc(100vh - '+HeadNavHeight+'px);'"
@scrolltolower="loadingPulldown">
<view class="list">
<view class="childBox" style="background-color: pink;">列表内容1</view>
<view class="childBox" style="background-color: yellow;">列表内容2</view>
<view class="childBox" style="background-color: red;">列表内容3</view>
<view class="childBox" style="background-color: coral;">列表内容4</view>
<view class="childBox" style="background-color: aqua;">列表内容5</view>
</view>
</scroll-view>
</view>
</template>
<script>
// 引入组件
import HeadNav from '../../components/HeadNav/HeadNav.vue';
export default {
data() {
return {
HeadNavHeight: 0
}
},
onShow() {
},
onLoad() {
},
onHide() {
},
methods: {
// 上拉加载
loadingPulldown() {
console.log('上拉加载');
},
// 导航栏高度(单位px)
getHeadHeight(e) {
this.HeadNavHeight = e
console.log(this.HeadNavHeight);
},
},
// 注册
components: {
HeadNav
}
}
</script>
<style scoped lang="scss">
.childBox {
text-align: center;
height: 400rpx;
line-height: 400rpx;
margin-top: 100rpx;
}
</style>
上一篇: 简单的 iOS 导航栏渐变色解决方案