天天看点

微信小程序自定义导航栏(兼容适配所有机型)

在开发微信小程序的过程中,我们发现只是官方默认的header头部,满足不了设计需求,这里我们以Uni App为例讲解一下。

官方文档:navigationStyle 导航栏样式,仅支持 default/custom。custom 模式可自定义导航栏,只保留右上角胶囊状的按钮)。

文档地址: https://uniapp.dcloud.io/collocation/pages?id=pages

微信小程序自定义导航栏(兼容适配所有机型)
1、不同的机型,状态栏的高度是不一样的
uni.getSystemInfo({
    success:function(e){
		Vue.prototype.windowHeight = e.windowHeight *2
		Vue.prototype.statusBar    = e.statusBarHeight *2
		Vue.prototype.customBar    = 88
		if(e.platform == "devtools"){
		     Vue.prototype.platformType ='devtools'
		}else if(e.platform == "ios"){
             Vue.prototype.platformType ='ios'
		}else if(e.platform == "android"){
             Vue.prototype.platformType ='android'
		}
    }
})
           
2、根据状态栏高度,编写header组件
<template>
    <view class="hy-body-wrap" :style="{'padding-top':style}">
		<image v-if="baseUrl && backImg" class="back-box" :src="baseUrl+'user/back-user.png'" :style="{'height':style}"></image>
		<view class="c-head-wrap" :class="[{'g-border':borderAsync},{'back':!backImg}]" :style="{'padding-top': statusBarH + 'rpx'}">
			<view class="head-flex-box" :style="[{'height': customBarH + 'rpx', 'color': titleTintColor}, bgColor]">
			    <!-- 返回 -->
			    <view v-if="isBack" @tap="goBack" class="go-back-btn g-cen-y">
						
			    </view>
				<view v-else class="right-back"></view>
			    <!-- <slot name="headerL"></slot> -->
			    <!-- 标题 -->
			    <view :class="[{'text-left':platformType !='ios'},{'ff':backImg}]" class="head-title flex1 g-cen-cen" v-if="title">
			        {{title}}
			    </view>
			    <view class="flex1" :class="[searchRadius ? 'uni_searchRadius' : '']" v-if="search"> />
			        <input class=" flex1" type="text" placeholder="搜索" placeholder-style="color: rgba(255,255,255,.5);" />
			    </view>
			    <!-- 右侧 -->
			    <view class="right-back">
			        <slot name="iconfont"></slot>
			        <slot name="string"></slot>
			        <slot name="image"></slot>
			    </view>
			</view>
		</view>
        
		<slot name="body"></slot>
		<slot name="nav"></slot>
		<slot name="search"></slot>
    </view>
</template>
 
<script>
import {mapActions,mapGetters} from 'vuex'
export default {
	data() {
		return {
			statusBarH: this.statusBar,
			customBarH: this.customBar
		}
	},
	props: {
		isBack: { type: [Boolean, String], default: true },
		title: { type: String, default: '' },
		titleTintColor: { type: String, default: '#343434' },
		bgColor: Object,
		center: { type: [Boolean, String], default: false },
		search: { type: [Boolean, String], default: false },
		searchRadius: { type: [Boolean, String], default: false },
		fixed: { type: [Boolean, String], default: false },
		hei:{type:Number,default:0},
		borderAsync:{type:Boolean,default:false},
		backImg:{type:Boolean,default:false}
	},
	computed: {
		style() {
			let hei = `${this.customBarH+this.statusBarH+this.hei}rpx`;
			let _style = hei;
			this.setStatusBarH(this.customBarH+this.statusBarH+'rpx');
			return _style
		},
		...mapGetters(['baseUrl'])
		
	},
	methods: {
		...mapActions(['setStatusBarH']),
		goBack() {
			uni.navigateBack()
		}
	}
}
</script>
<style lang="scss" scoped>
.hy-body-wrap{
	.back-box{
		position: fixed;
		left: 0;
		top: 0;
		width: 100%;
		z-index: 12;
	}
	.c-head-wrap{
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		z-index: 100;
		&.back{
			background-color: #fff;
		}
		.head-flex-box{
			display: flex;
			align-items: center;
			position: relative;
			.flex1{
				flex:1;
			}
			.head-title{
				font-size: 32px;
				&.ff{
					color: #fff;
				}
				&.text-left{
					justify-content: flex-start;
				}
			}
			.go-back-btn{
				padding-left: 31px;
				height: 100%;
				width:80px ;
				box-sizing: border-box;
				&::after{
					content: "";
					width: 14px;
					height: 28px;
					background: url($baseUrl+'icon/jiao-left.png') no-repeat center;
					background-size: cover;
				}
			}
			.right-back{
				width: 30px;
				height: 100%;
			}
			
		}
	}
}
</style>
           
3、引用方式
<template>
	<section class="work-wrap" >
		<header-box :isBack="false" title="这时title内容" />
	</section>
</template>
<script>
import api from "$api"
import headerBox from '$common/header/headerBox'
export default {
	data() {
		return {
			
		};
	},
	components:{
		headerBox
	}
}
</script>