欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

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>