uniapp微信小程序自定义导航栏的全过程

目录
  • 前言
  • 那么标题栏的高度我们怎么获取呢?
  • 献上源码:
  • 组件使用:
  • 效果图:
  • 总结

前言

相信很多小伙伴在使用uniapp进行多端开发的时候呢,在面对一些奇葩的业务需求的时候,uniapp给我们提供的默认导航栏已经不能满足我们的业务需求了,这个时候就需要我们自己自定义导航栏使用啦。

当然uniapp也给我们提供了很多的自定义导航栏的插件供大家使用,今天也给大家分享一个我自己写的导航栏啦,希望大家多多指点

首先我们在自定义导航栏的时候,我们需要知道头部的导航栏有哪几部分组成,那么我们以微信小程序为例

可以看到在微信小程序中,我们的头部导航栏其实受到右上角胶囊的限制比较大,这个时候我们自定义的导航栏,需要做到标题于胶囊水平对齐,那其实这个时候整个头部其实主要又:状态栏的高度+标题栏的高度组成。

状态栏的高度我们可以通过uni.getSystemInfoSync().statusBarHeight来获取。

那么标题栏的高度我们怎么获取呢?

其实要想定义标题栏的高度,我们需要知道这个胶囊的位置,在小程序中我们可以使用wx.getMenuButtonBoundingClientRect()获取关于胶囊的信息

获取到的胶囊的top,left,right分别对应胶囊的上边界,左边界,右边界相对于屏幕左上角的起点的位置,所以我们是不是可以用(胶囊上边界距离顶部的距离 - 状态栏的高度)*2+胶囊的高度,就是标题栏的高度呢?然后再在标题栏里面添加一个文本区让他的高度等于胶囊的高度,实现flex布局的上下居中是不是就搞定了呢?

以上呢其实针对小程序平台的导航栏讲解,那么既然使用uniapp,就会考虑到多端情况

那么其实我们使用uniapp获取到的状态栏在h5,小程序和app原生都是有效的,h5网页中一般我们都是直接采用浏览器内核给我们内置的网页导航栏,就是一个头部,没有过多的要求,而且浏览器不同,给我们提供的头部导航也不一样。

而对于app端,我们没有了像微信小程序中那种让人心烦的胶囊之后,我们只需要知道状态栏的高度,然后加上自己业务需求的标题栏样式和标题栏高度就行啦

所以我们在进行自定义导航栏封装的时候就要对代码进行条件编译啦。那么我这里呢是把微信小程序做了单独的处理,微信小程序之外的平台看作是统一状态

献上源码:

首先我们把获取设备信息的代码封装到一个统一的js文件里面,这样方便我们在组件中获取也方便我们在页面中获取。

/**
 * 此js文件管理关于当前设备的机型系统信息
 */
const systemInfo = function() {
	/****************** 所有平台共有的系统信息 ********************/
	// 设备系统信息
	let systemInfomations = uni.getSystemInfoSync()
	// 机型适配比例系数
	let scaleFactor = 750 / systemInfomations.windowWidth
	// 当前机型-屏幕高度
	let windowHeight = systemInfomations.windowHeight * scaleFactor //rpx
	// 当前机型-屏幕宽度
	let windowWidth = systemInfomations.windowWidth * scaleFactor //rpx
	// 状态栏高度
	let statusBarHeight = (systemInfomations.statusBarHeight) * scaleFactor //rpx

	// 导航栏高度  注意:此导航栏高度只针对微信小程序有效 其他平台如自定义导航栏请使用:状态栏高度+自定义文本高度
	let navHeight = 0 //rpx
	// console.log(windowHeight,'哈哈哈哈哈');

	/****************** 微信小程序头部胶囊信息 ********************/
	// #ifdef MP-WEIXIN
	const menuButtonInfo = wx.getMenuButtonBoundingClientRect()
	// 胶囊高度
	let menuButtonHeight = menuButtonInfo.height * scaleFactor //rpx
	// 胶囊宽度
	let menuButtonWidth = menuButtonInfo.width * scaleFactor //rpx
	// 胶囊上边界的坐标
	let menuButtonTop = menuButtonInfo.top * scaleFactor //rpx
	// 胶囊右边界的坐标
	let menuButtonRight = menuButtonInfo.right * scaleFactor //rpx
	// 胶囊下边界的坐标
	let menuButtonBottom = menuButtonInfo.bottom * scaleFactor //rpx
	// 胶囊左边界的坐标
	let menuButtonLeft = menuButtonInfo.left * scaleFactor //rpx

	// 微信小程序中导航栏高度 = 胶囊高度 + (顶部距离 - 状态栏高度) * 2
	navHeight = menuButtonHeight + (menuButtonTop - statusBarHeight) * 2
	// #endif

	// #ifdef MP-WEIXIN
	return {
		scaleFactor,
		windowHeight,
		windowWidth,
		statusBarHeight,
		menuButtonHeight,
		menuButtonWidth,
		menuButtonTop,
		menuButtonRight,
		menuButtonBottom,
		menuButtonLeft,
		navHeight
	}
	// #endif

	// #ifndef MP-WEIXIN
	return {
		scaleFactor,
		windowHeight,
		windowWidth,
		statusBarHeight
	}
	// #endif
}

export {
	systemInfo
}

然后我们定义一个导航栏组件

/*
* 注意:
* 1、在传入宽度或者高度时,如果是Number数据,传入的值为px大小,无需带单位,组件自动计算
* 2、在使用此导航栏时,建议传入UI规定的导航栏高度,此高度只针对除微信小程序的其他平台有效,微信小程序的导航栏高度,组件自计算
*/
<template>
	<view>
		<!-- 微信小程序头部导航栏 -->
		<!-- #ifdef MP-WEIXIN -->
		<view class="wx-head-mod" :style="{height:navHeight+'rpx',backgroundColor:navBackgroundColor}">
			<view class="wx-head-mod-nav" :style="{height:navigationBarHeight+'rpx',top:statusBarHeight+'rpx'}">
				<view class="wx-head-mod-nav-content"
					:style="{height:customHeight+'rpx',justifyContent:textAlign === 'center'?'center':'left'}">
					<!-- 文本区 -->
					<view class="wx-head-mod-nav-content-mian"
						:style="{width:navTextWidth,lineHeight:customHeight + 'rpx',paddingLeft:textPaddingLeft*scaleFactor+'rpx',fontSize:fontSize*scaleFactor+'rpx',fontWeight:fontWeight,color:titleColor}">
						{{textContent}}
					</view>
					<!-- 返回按钮 -->
					<view class="wx-head-mod-nav-content-back" :style="{display:isBackShow?'flex':'none'}"
						@click="backEvent">
						<view class="wx-head-mod-nav-content-back-img"
							:style="{width:backImageWidth*scaleFactor+'rpx',height:backImageHeight*scaleFactor+'rpx'}">
							<image :src="backImageUrl" mode="" style="width: 100%;height: 100%;"></image>
						</view>
					</view>
				</view>
			</view>
		</view>
		<!-- #endif -->

		<!-- 除微信小程序之外的其他设备 -->
		<!-- #ifndef MP-WEIXIN -->
		<view class="other-head-mod"
			:style="{height:navHeightValue*scaleFactor+statusBarHeight+'rpx',backgroundColor:navBackgroundColor}">
			<view class="other-head-mod-mian"
				:style="{height:navHeightValue*scaleFactor+'rpx',justifyContent:textAlign === 'center'?'center':'left'}">
				<!-- 返回按钮 -->
				<view class="other-head-mod-mian-back" v-show="isBackShow" @click="backEvent">
					<view class="other-head-mod-mian-back-img"
						:style="{width:backImageWidth*scaleFactor+'rpx',height:backImageHeight*scaleFactor+'rpx'}">
						<image :src="backImageUrl" mode="" style="width: 100%;height: 100%;"></image>
					</view>
				</view>
				<!-- 标题 -->
				<view class="other-head-mod-mian-title" :style="{width:windowWidth - 184+'rpx',lineHeight:navHeightValue*scaleFactor+'rpx',
					paddingLeft:textPaddingLeft*scaleFactor+'rpx',fontSize:fontSize*scaleFactor+'rpx',
					fontWeight:fontWeight,color:titleColor}">
					{{textContent}}
				</view>
			</view>
		</view>
		<!-- #endif -->
	</view>
</template>

<script>
	const app = getApp()
	import {systemInfo} from '@/common/system-info.js'
	export default {
		name: "HeadView",
		props: {
			// 文本区域位置 left:左  center:中
			textAlign: {
				type: String,
				default: 'center'
			},
			// 文本区内容
			textContent: {
				type: String,
				default: '哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈就啊哈哈好借好还'
			},
			// 文本区离左边的距离
			textPaddingLeft: {
				type: Number,
				default: 16
			},
			// 是否需要返回按钮
			isBackShow: {
				type: Boolean,
				default: true
			},
			// 文本区字体大小
			fontSize: {
				type: Number,
				default: 20 //px
			},
			// 文本区字体粗细
			fontWeight: {
				type: Number,
				default: 700
			},
			// 文本区返回按钮图片宽
			backImageWidth: {
				type: Number,
				default: 12 //px
			},
			// 文本区返回按钮图片高
			backImageHeight: {
				type: Number,
				default: 24 //px
			},
			// 返回按钮图标路径
			backImageUrl: {
				type: String,
				default: '/static/backImage.svg'
			},
			// 导航栏整体背景颜色
			navBackgroundColor: {
				type: String,
				default: '#2476F9'
			},
			// 标题字体颜色
			titleColor: {
				type: String,
				default: '#ffffff',
			},

			/******** h5端,app端需要传入自定义导航栏高度 *******/
			navHeightValue: {
				type: Number,
				default: 44 //px
			}
		},
		computed: {
			// 文本区宽度
			navTextWidth() {
				if (this.textAlign === 'center') {
					return (this.windowWidth - (this.windowWidth - this.menubarLeft) * 2) + 'rpx'
				} else {
					return this.menubarLeft + 'rpx'
				}
			},
			// 文本区paddingLeft
			textPaddingleft() {
				if (this.textAlign === 'center') {
					return '0'
				} else {
					return this.textPaddingLeft + 'rpx'
				}
			}
		},
		data() {
			return {
				statusBarHeight: app.globalData.statusBarHeight, //状态栏高度
				navHeight: app.globalData.navHeight, //头部导航栏总体高度
				navigationBarHeight: app.globalData.navigationBarHeight, //导航栏高度
				customHeight: app.globalData.customHeight, //胶囊高度
				scaleFactor: app.globalData.scaleFactor, //比例系数
				menubarLeft: app.globalData.menubarLeft, //胶囊定位的左边left
				windowWidth: app.globalData.windowWidth * app.globalData.scaleFactor
			};
		},
		methods: {
			backEvent() {
				uni.navigateBack({
					delta: 1
				})
			}
		},
		created() {
			/* 获取设备信息 */
			const SystemInfomations = systemInfo()
			/* 通用平台 */
			this.statusBarHeight = SystemInfomations.statusBarHeight //状态栏高度
			this.scaleFactor = SystemInfomations.scaleFactor //比例系数
			this.windowWidth = SystemInfomations.windowWidth //当前设备的屏幕宽度
			/* 微信小程序平台 */
			// #ifdef MP-WEIXIN
			this.navHeight = SystemInfomations.navHeight + SystemInfomations.statusBarHeight //头部导航栏总高度
			this.navigationBarHeight = SystemInfomations.navHeight //头部导航栏高度
			this.customHeight = SystemInfomations.menuButtonHeight //胶囊高度
			this.menubarLeft = SystemInfomations.menuButtonLeft //胶囊左边界距离左上角的距离
			// #endif

		}
	}
</script>

<style>
	/* #ifdef MP-WEIXIN */
	.wx-head-mod {
		box-sizing: border-box;
		width: 100%;
		position: fixed;
		top: 0;
		left: 0;
	}

	.wx-head-mod-nav {
		box-sizing: border-box;
		width: 100%;
		position: absolute;
		left: 0;
		display: flex;
		justify-content: center;
		align-items: center;

	}

	.wx-head-mod-nav-content {
		box-sizing: border-box;
		width: 100%;
		display: flex;
		justify-content: left;
		align-items: center;
		position: relative;
	}

	/* 文本区 */
	.wx-head-mod-nav-content-mian {
		box-sizing: border-box;
		height: 100%;
		white-space: nowrap;
		text-overflow: ellipsis;
		overflow: hidden;
	}

	/* 返回按钮 */
	.wx-head-mod-nav-content-back {
		box-sizing: border-box;
		width: 60rpx;
		height: 100%;
		/* background-color: aqua; */
		position: absolute;
		top: 0;
		left: 32rpx;
		display: flex;
		align-items: center;
		justify-content: left;
	}

	.wx-head-mod-nav-content-back-img {
		box-sizing: border-box;
	}

	/* #endif */

	/* #ifndef MP-WEIXIN */
	.other-head-mod {
		box-sizing: border-box;
		width: 100%;
		position: fixed;
		top: 0;
		left: 0;
	}

	.other-head-mod-mian {
		box-sizing: border-box;
		width: 100%;
		display: flex;
		align-items: center;
		justify-content: left;
		position: absolute;
		left: 0;
		bottom: 0;
	}

	/* 返回按钮 */
	.other-head-mod-mian-back {
		box-sizing: border-box;
		height: 100%;
		width: 60rpx;
		position: absolute;
		left: 32rpx;
		top: 0;
		display: flex;
		align-items: center;
	}

	/* 标题 */
	.other-head-mod-mian-title {
		box-sizing: border-box;
		height: 100%;
		white-space: nowrap;
		text-overflow: ellipsis;
		overflow: hidden;
	}

	/* #endif */
</style>

组件使用:

引入组件:

import HeadNav from '@/components/HeadNav.vue'

组册组件:

components:{
			HeadNav
		},
<template>
	<view class="content">
		<head-nav></head-nav>
		<view class="content-main"></view>
	</view>
</template>

效果图:

微信小程序:

h5:

app:

在项目里面没有针对h5时候需要导航栏做特别的限制,如果实际开发中在h5端不需要此导航栏,请在模版上面针对h5页面加入条件编译即可。

总结

到此这篇关于uniapp微信小程序自定义导航栏的文章就介绍到这了,更多相关uniapp自定义导航栏内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • uni-app自定义导航栏按钮|uniapp仿微信顶部导航条功能

    最近一直在学习uni-app开发,由于uniapp是基于vue.js技术开发的,只要你熟悉vue,基本上很快就能上手了. 在开发中发现uni-app原生导航栏也能实现一些顶部自定义按钮+搜索框,只需在page.json里面做一些配置即可.设置app-plus,配置编译到App平台的特定样式.dcloud平台对app-plus做了详细说明:app-plus配置,需注意 目前暂支持H5.App端,不支持小程序. 在page.json里配置app-plus即可 { "path": "

  • uniapp微信小程序自定义导航栏的全过程

    目录 前言 那么标题栏的高度我们怎么获取呢? 献上源码: 组件使用: 效果图: 总结 前言 相信很多小伙伴在使用uniapp进行多端开发的时候呢,在面对一些奇葩的业务需求的时候,uniapp给我们提供的默认导航栏已经不能满足我们的业务需求了,这个时候就需要我们自己自定义导航栏使用啦. 当然uniapp也给我们提供了很多的自定义导航栏的插件供大家使用,今天也给大家分享一个我自己写的导航栏啦,希望大家多多指点 首先我们在自定义导航栏的时候,我们需要知道头部的导航栏有哪几部分组成,那么我们以微信小程序

  • 微信小程序自定义导航栏

    本文实例为大家分享了微信小程序自定义导航栏,供大家参考,具体内容如下 在微信小程序中导航栏是可以直接配置的: 目前只支持二种,但是我们的需求可能需要一个其他的颜色等,那么不得不修改这个了, "window":{ "navigationStyle": "custom" }, 我就配置了这个属性,现在来看看我的界面 红色箭头指向的是配置后自动生成的,我没有写任何代码,比如我在更多界面导航栏需要自定义,那么在more.js中在onLoad()方法中获取

  • 微信小程序自定义导航栏(模板化)

    前段时间写过一篇关于微信小程序自定义导航栏的自定义组件,但是对于分享页有一定的bug 这次用模板化又搞了一遍 优化了下Android与IOS 显示更接近微信原生的导航栏,以及修复分享页面不显示返回首页按钮 如果大家不习惯模板化的话可以 针对自己的需求拿以前封装的组件化做一些修改 微信小程序自定义导航栏(组件化) CustomNavBar.wxml <template name="CustomNavBar"> <block wx:if="{{ showNavB

  • 微信小程序自定义导航栏效果

    本文实例为大家分享了微信小程序自定义导航栏的具体代码,供大家参考,具体内容如下 第一步 添加属性 “navigationStyle”: “custom” 全局: app.json中添加属性 “navigationStyle”: “custom” "window": {     "backgroundTextStyle": "light",     "navigationBarBackgroundColor": "#f

  • 微信小程序自定义导航栏实例代码

    背景 在做快狗打车小程序时,关于默认导航栏,我们遇到了以下的问题: Android.IOS手机对于页面title的展示不一致,安卓title的显示不居中 页面的title只支持纯文本级别的样式控制,不能够做更丰富的title效果 左上角的事件无法监听.定制 路由导航单一,只能够返回上一页,深层级页面的返回不够友好 我们希望的是:在各个机型页面上title一致性 & 个性化展示.取得左上角点击事件控制权及深层级页面的一键返回 实现 step1 自定义 第一步 取得导航栏的控制权 小程序支持自定义导

  • 微信小程序自定义导航教程(兼容各种手机)

    前言 本文主要给大家介绍了关于微信小程序自定义导航的相关内容,详细代码请见github,请点击地址 (本地下载),其中有原生小程序的实现,也有wepy版本的实现 了解小程序默认导航 如上图所示,微信导航分为两部分,第一个部分为statusBarHeight,刘海屏手机(iPhone X,小米8等)会比其他的手机高很多,第二部分为titleBarHeight,安卓和IOS的高度不同,但是IOS高度是一样的,IOS高度是一样的, 所以我们要实现一个兼容不同手机的导航必须要根据不同的手机实现statu

  • 小程序自定义导航栏兼容适配所有机型(附完整案例)

    前言 大部分情况下我们都是使用微信官方自带的 navigationBar 配置 ,但有时候我们需要在导航栏集成搜索框.自定义背景图.返回首页按钮等. 思路 隐藏官方导航栏 获取胶囊按钮.状态栏相关数据以供后续计算 根据不同机型计算导航栏高度 编写新的导航栏 页面引用自定义导航 正文 隐藏官方导航栏 隐藏导航栏可以全局配置,也可以单独页面配置,具体根据业务需求来. 全局隐藏 //app.json "window": { "navigationStyle": "

  • 微信小程序自定义导航的方法

    本文实例为大家分享了微信小程序自定义导航的具体代码,供大家参考,具体内容如下 在app.js中获取状态栏信息和胶囊按钮信息 onLaunch() {     // 展示本地存储能力     const logs = wx.getStorageSync('logs') || []     logs.unshift(Date.now())     wx.setStorageSync('logs', logs)     // 获取系统信息     this.globalData.systemInfo

  • 微信小程序自定义导航隐藏和显示功能

    微信小程序中不能直接操作window对象,document文档,跟html的树结构不相同. 实现类似导航的隐藏显示,如图效果: 点击网络显示或隐藏网络中包含的内容.其他类似. 如果是jquery很方便实现,能直接操作document.在微信小程序中实现思路是:在逻辑层定义变量,通过setData赋值. 方法一:通过变量直接赋值,给每一个要控制显示的view定义变量 .wxml 代码: <!--index.wxml--> <view class="navView" bi

  • 微信小程序MUI导航栏透明渐变功能示例(通过改变opacity实现)

    本文实例讲述了微信小程序MUI导航栏透明渐变功能.分享给大家供大家参考,具体如下: 导航栏透明渐变效果 实现原理 1. 利用position:absolute在导航下定位一个view作为背景渐变使用; 2. 通过改变改view的opacity来实现透明渐变. WXML <!--pages/scroll/scroll.wxml--> <view style="height:100%;position:fixed;width:100%;"> <scroll-v

随机推荐