You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

249 lines
8.8 KiB

<script lang="ts" setup>
/*
* @description: 头部组件
* @fileName: Header.vue
* @params
* @author: lxx
* @date: 2023-07-16 09:32:09
* @version: V1.0.2
*/
import { goToPage } from '../libs/util'
import { type CSSProperties, computed, ref, watchEffect } from 'vue'
type headerInt = {
title: string
// 头部高度 默认为44px (微信小程序不可用)
headerHeight?: number
// 是否显示左侧内容
leftIconShow?: boolean
// 样式部分
backgroundColor?: string
backgroundColor2?: string
textColor?: string
textFontSize?: number
// 是否需要生成和头部高度相同的盒子
isShowHeaderBox?: boolean
positionState?: string
isShowShadow?: boolean
isBlackIcon?: boolean
// 头部没有右侧盒子,true:左中右结构 false:左中结构(小程序可以为左中右结构但是没有右侧盒子)
isHaveRightBox?: boolean
}
const props = withDefaults(defineProps<headerInt>(), {
// 头部高度 默认为44px (微信小程序不可用)
headerHeight: 44,
// 是否显示左侧内容
leftIconShow: true,
// 样式部分
backgroundColor: '#ffffff', //linear-gradient(90deg, rgba(10, 207, 254, 1) 0%, rgba(74, 92, 255, 1) 100%)
backgroundColor2: '#ffffff',
textColor: '#000',
textFontSize: 34,
title: '标题',
// 是否需要生成和头部高度相同的盒子
isShowHeaderBox: true,
positionState: 'fixed',
isShowShadow: false,
isBlackIcon: true, // 是否为黑色图标
isHaveRightBox: true
})
let { statusBarHeight } = uni.getSystemInfoSync()
// #ifdef MP-WEIXIN
// 胶囊状态
let menuButton = uni.getMenuButtonBoundingClientRect()
// 微信头部宽度
let wxHeaderWidth = menuButton.left - 10
// 上边距
statusBarHeight = menuButton.top
// #endif
// padding的高度(防止头部塌陷)
const fillBoxHeight = ref(statusBarHeight + 3)
// 设置header的高度
const headerHeightRef = ref(0)
watchEffect(() => {
headerHeightRef.value = props.headerHeight
// #ifdef MP-WEIXIN
// 中间高度
headerHeightRef.value = menuButton.height
// #endif
})
// console.log('statusBarHeight', statusBarHeight)
const style = computed(() => {
return {
boxShadow: props.isShowShadow ? '0 0 8rpx -3rpx #333' : '0 0 0 0 #333',
background: props.backgroundColor,
color: props.textColor,
position: props.positionState
} as CSSProperties
})
// 返回上一页(如没有页面返回首页)
const goBack = () => {
if (getCurrentPages().length <= 1) {
goToPage({
url: 'pages/index/index',
mode: 'redirectTo'
})
} else {
uni.navigateBack()
}
}
const backIcon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAACMklEQVR4nO2av0uVURjHPyiEYgkuoVC4ODSK2pRDYFOENOQP6A+IEgknkWgKgqTEP6AaHIKyhqhGiSgVpKwGBweLBMHZcjAK47xcXrxxn6el5/pwzvnAme5wv5/ve+/hPO/7kslkMplMxjsjwCdgB7iV2tW6Aez/tW46yFUXpmvIh/U6AXfuCvJhnXOQz5R7ivz1iL0LZhX5Sw7ymTIviG8DpyP2pg14Kch/BjodZDSjHdgQ5D8CrZF6F3QD3wT5VeCog4xm9ADfBfn3scv3KvJhL2hxkNGMsJv/EOQfRepcchbYFeQnnWQ046JywLkSqXPJlCJ/2UlGM7Rz/WikziX3BfFfwLCTjGY8FuR/Av2ROpdIQ004159yktGMZ4L8Yuzn+mZgQZB/BTQ6yGhGOLevCPIvInUu6QK+CPLPnWQ05Z0gPxuxcxXSIWfAUUZT5oQCfgPXIvau4onyS5hwlNOUB0oJcxF7V6ENPuFofMRRVjNuKyW8SaWEIaWEt0CTg4zmDCq3v5ZSKUG7AboMdDjIaE6fUsJX4ETk/gU9lddbapWwncLzfiqPwTaVzfGCg4zmdCiTYxJ3iPnHo/CwrjrIWBeeKiWMJeBfoM0P4w7y1YUZpYQ7CfgXaEPUtIN8dUF6KXK/cqu9IYEOincApRIWU5kfxpUS1oDjDjKacx7YE0rYSGWI6lXmh4f/60s8bywfKkPUVo3Pjh1CnkPjJLB+4OqHv8aZlArIZDKZTMYC4A8EQ0uQY7/3uAAAAABJRU5ErkJggg=='
const backIconW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAACjElEQVR4nO2azatNURiH364S+SgTuUUmBoa6GDEwuCNJBr7KHyAkGUkyUsoN3T8AA0r5GugyUZK4lHwODAwQpYwvBqQeve4+deK8a5+zz9q3d6+9nnonp7PXWb/n7L1aH1symUwmk8lUBpiL2gO8BmaAU/p7bpiD8Cf4n5NtETDRI7zywEH0WWoMf9YIr4x7yP6XmsKfC4Q/kvoYMBkIv7PzPTdEDn/DCP4V2Nj93dQELAPuGOHfAKv/vcYNEcKvAN4b4V8BS3tdl4qAdcAnI/xLYLF1rRuGCD8GfDPCPw+FT0HA+kB4HQsWlbXhhgrhdTT/boS/2m87TRWwBfhhhD82SFtuGKDTO4zgyv5B76SmCTgeCL+vyjjihj46G5rX7604iDZGwAUj+G9gd9XwTRFwzQj/C9g8TPgmCLAWNTqvXztseO8Cbhnhp615fSoCFgL3jfB3gXmxwnsUoPP2Z0b4qZjBPQpYA3wwwt+uI7w3AY+N8JN1hY8pYCRCG5uMz6citF07MQRcMT6/JyIHHWWth+KWvG48BsrR1MeATl0MSLjcBgFSsvDRqfH81AVonQ5IeBhLghuMDu4KSHgELEhdgNb2wPbXk2EluKGko6EN0KfAaOoCtDYEJHwEVqYuQIpDkBlDgh58jqcuQIpjsM+BwXFb6gKkeOatlSOD7BC7ocLzGzoKVw6kLqBTNwMSDrVBgJSsHw63QYDW+YCEM20QICWLqIk2CJDAS5EUW+0jqQuQ4h1Ai+nu9YMbIguQYvCzeAssT12A1lbgpyFB3ygbdRB9lpoESPEekbV+uBSr/zF2hevihYiMiciXHu0vcdPLGu+ATq0C3nX9+/poWGcRmUwmk8lk+kRE/gCfWLdyj0KPNgAAAABJRU5ErkJggg=='
</script>
<template>
<!-- #ifndef MP-TOUTIAO -->
<view class="header_box">
<view class="header_main" :style="style">
<view class="status_bar" :style="{ height: statusBarHeight + 'px' }"></view>
<!-- 标准的左中右结构 -->
<view v-if="isHaveRightBox" class="header flex-center-between" :style="{ height: headerHeightRef + 'px' }">
<view class="header_left flex-center-between">
<slot name="left">
<view v-if="leftIconShow" class="icon flex" @click="goBack">
<image :src="isBlackIcon ? backIcon : backIconW" mode="widthFix"></image>
</view>
</slot>
</view>
<view class="header_center">
<slot>
<view class="title" :style="{ fontSize: textFontSize + 'rpx' }">
{{ title }}
</view>
</slot>
</view>
<view class="header_right flex">
<!-- #ifndef MP-WEIXIN -->
<slot name="right"></slot>
<!-- #endif -->
</view>
</view>
<!-- 左右结构 -->
<view v-else class="wx_header flex"
:style="{ height: headerHeightRef + 'px', width: wxHeaderWidth + 'px' }">
<view class="wx_header_left flex">
<slot name="left">
<view class="icon flex" @click="goBack" v-if="leftIconShow">
<image :src="isBlackIcon ? backIcon : backIconW" mode="widthFix"></image>
</view>
</slot>
</view>
<view class="wx_header_txt flex">
<slot name="center">
<view class="title" :style="{ fontSize: textFontSize + 'rpx' }">
{{ title }}
</view>
</slot>
</view>
</view>
</view>
<!-- 填充头部防止塌陷 新加(v-if="isShowHeaderBox") -->
<view class="status_bar" v-if="isShowHeaderBox" :style="{ height: fillBoxHeight + 'px' }"></view>
<!-- #ifdef MP-WEIXIN -->
<view v-if="isShowHeaderBox" :style="{ height: headerHeightRef + 4 + 'px', background: backgroundColor2 }">
</view>
<!-- #endif -->
<!-- 待测试 -->
<!-- #ifndef MP-WEIXIN -->
<view v-if="isShowHeaderBox" :style="{ height: headerHeightRef + 'px', background: backgroundColor2 }"></view>
<!-- #endif -->
</view>
<!-- #endif -->
</template>
<style lang="scss" scoped>
.header_box {
// padding: 0 20rpx 5rpx;
// background-color: #fff;
}
.header_main {
width: 100%;
z-index: 9999;
top: 0;
left: 0;
/* #ifdef MP-WEIXIN */
padding: 0 20rpx 15rpx;
/* #endif */
/* #ifndef MP-WEIXIN */
padding: 5rpx 20rpx;
/* #endif */
box-sizing: border-box;
.img {
width: 48rpx;
height: 48rpx;
}
.header {
// padding: 0 16rpx;
box-sizing: border-box;
.header_left {
width: 20%;
.icon {
width: 48rpx;
}
.left_txt {
font-size: 22rpx;
line-height: 22rpx;
}
}
.header_center {
width: 60%;
text-align: center;
font-size: 28rpx;
.title {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.header_right {
width: 20%;
}
}
.wx_header {
.wx_header_left {
height: 100%;
.icon {
width: 48rpx;
image {
vertical-align: middle;
width: 100%;
}
}
}
.wx_header_txt {
flex: 1;
height: 100%;
padding-left: 26rpx;
.title {
width: 100%;
line-height: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 28rpx;
}
}
}
}
</style>
../../libs/util