Files
RentWeAppFront/components/navbar/customNavbar.vue

225 lines
4.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view
class="custom-navbar"
:class="{ 'transparent': isTransparent, 'opaque': !isTransparent }"
:style="{
paddingTop: statusBarHeight + 'px',
height: navHeight + 'px',
// 使用rgba颜色值控制背景透明度而不是整个元素的opacity
backgroundColor: `rgba(${hexToRgb(bgColor)}, ${opacity})`
}"
>
<view class="nav-content">
<!-- 左侧返回 -->
<view class="nav-left">
<u-icon
name="arrow-left"
size="44"
:color="textColor"
@click="onBack"
v-if="showBack"
></u-icon>
<u-icon
name="home"
size="44"
:color="textColor"
@click="goHome"
v-if="showHome"
></u-icon>
</view>
<!-- 中间标题 -->
<view class="nav-title" :style="{ color: textColor }">{{ title }}</view>
<!-- 右侧按钮位于胶囊左侧 -->
<view
class="nav-right"
:style="{ marginRight: menuRightGap + 'px' }"
>
<view
v-for="(btn, index) in rightButtons"
:key="index"
class="nav-btn"
@click="btn.onClick && btn.onClick()"
>
<u-icon
:name="btn.icon"
:color="btn.color || textColor"
:size="btn.size || 40"
></u-icon>
</view>
<!-- 额外的右侧图标 -->
<view class="nav-btn" v-for="(icon, index) in extraIcons" :key="index" @click="onExtraIconClick(index)">
<u-icon
:name="icon"
:color="textColor"
size="40"
></u-icon>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'customNavbar',
props: {
title: {
type: String,
default: '',
},
rightButtons: {
type: Array,
default: () => [],
},
back: {
type: Function,
default: null,
},
// 导航栏样式控制
isTransparent: {
type: Boolean,
default: false
},
bgColor: {
type: String,
default: '#ffffff'
},
textColor: {
type: String,
default: '#333333'
},
opacity: {
type: Number,
default: 1
},
extraIcons: {
type: Array,
default: () => []
},
// 按钮显示控制
showBack: {
type: Boolean,
default: true // 左侧返回按钮默认显示
},
showHome: {
type: Boolean,
default: false // 回首页按钮默认不显示
}
},
data() {
return {
statusBarHeight: 0,
navHeight: 0,
menuRightGap: 0, // 胶囊按钮与右侧边距
};
},
mounted() {
const systemInfo = uni.getSystemInfoSync();
const menuButton = wx.getMenuButtonBoundingClientRect
? wx.getMenuButtonBoundingClientRect()
: null;
if (menuButton) {
this.statusBarHeight = systemInfo.statusBarHeight;
this.navHeight =
menuButton.bottom + menuButton.top - systemInfo.statusBarHeight;
this.menuRightGap =
systemInfo.screenWidth - menuButton.right + 8; // 适度留一点间隙
} else {
// 其他端
this.statusBarHeight = systemInfo.statusBarHeight;
this.navHeight = 90;
this.menuRightGap = 16;
}
},
methods: {
// 十六进制颜色转RGB
hexToRgb(hex) {
// 移除#号
hex = hex.replace(/^#/, '');
// 处理缩写形式(如#RGB
if (hex.length === 3) {
hex = hex.split('').map(char => char + char).join('');
}
// 解析RGB值
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
return `${r}, ${g}, ${b}`;
},
onBack() {
if (this.back) {
this.back();
} else {
uni.navigateBack();
}
},
goHome(){
uni.reLaunch({
url:'../index/index'
})
},
onExtraIconClick(index) {
// 额外图标点击事件,可通过事件冒泡传递给父组件
this.$emit('extra-icon-click', index);
}
},
};
</script>
<style lang="scss" scoped>
.custom-navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
transition: all 0.3s ease;
.nav-content {
display: flex;
align-items: center;
justify-content: space-between;
height: 100%;
padding: 0 24rpx;
}
.nav-left {
width: 50rpx;
display: flex;
align-items: center;
}
.nav-title {
flex: 1;
text-align: center;
font-size: 32rpx;
}
.nav-right {
display: flex;
align-items: center;
.nav-btn {
margin-left: 20rpx;
}
}
// 透明状态样式
&.transparent {
background-color: rgba(255, 255, 255, 0);
}
// 不透明状态样式
&.opaque {
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.08);
}
}
</style>