修改导航栏

This commit is contained in:
zpc 2025-04-22 02:42:51 +08:00
parent 4a5e422031
commit da23c1066d
3 changed files with 417 additions and 24 deletions

View File

@ -1,16 +1,51 @@
<template>
<view class="nav-header">
<uni-nav-bar :color="color" :backgroundColor="backgroundColor" :fixed="fixed" :statusBar="statusBar"
:border="border">
<template #left>
<view v-if="showBack" class="nav-header__back" @click="goBack">
<uni-icons :color="color" type="left" size="20" />
<view class="custom-nav-header" :class="{'custom-nav-header--dark': dark}">
<!-- 导航栏内容 -->
<view class="custom-nav-header__content" :class="{ 'custom-nav-header--fixed': fixed, 'custom-nav-header--shadow': shadow }"
:style="{ 'background-color': themeBgColor }">
<!-- 状态栏 -->
<view v-if="statusBar" class="custom-nav-header__status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
<!-- 导航内容 -->
<view class="custom-nav-header__header" :style="{ color: themeColor, backgroundColor: themeBgColor, height: navbarHeight + 'px' }">
<!-- 左侧区域 -->
<view @click="onClickLeft" class="custom-nav-header__header-btns custom-nav-header__header-btns-left" :style="{ width: leftWidth + 'px' }">
<slot name="left">
<view class="custom-nav-header__content-view" v-if="leftIcon">
<view class="custom-nav-header__icon" :style="{ 'border-color': themeColor }"></view>
</view>
<view class="custom-nav-header-btn-text" v-if="leftText">
<text :style="{ color: themeColor, fontSize: '14px' }">{{ leftText }}</text>
</view>
</slot>
</view>
<!-- 中间标题区域 -->
<view class="custom-nav-header__header-container" @click="onClickTitle">
<slot>
<view class="custom-nav-header__header-container-inner" v-if="innerTitle">
<text class="custom-nav-bar-text custom-nav-ellipsis-1" :style="{ color: themeColor }">{{ innerTitle }}</text>
</view>
</slot>
</view>
<!-- 右侧区域 -->
<view @click="onClickRight" class="custom-nav-header__header-btns custom-nav-header__header-btns-right" :style="{ width: rightWidth + 'px' }">
<slot name="right">
<view class="custom-nav-header-btn-text" v-if="rightText">
<text class="custom-nav-bar-right-text" :style="{ color: themeColor }">{{ rightText }}</text>
</view>
</slot>
</view>
</template>
<view style="font-size: 34rpx; width: 100%; display: flex; justify-content: center; align-items: center;">
{{ title }}
</view>
</uni-nav-bar>
</view>
<!-- 占位符 -->
<view class="custom-nav-header__placeholder" v-if="fixed">
<view v-if="statusBar" :style="{ height: statusBarHeight + 'px' }"></view>
<view class="custom-nav-header__placeholder-view" :style="{ height: navbarHeight + 'px' }"></view>
</view>
</view>
</template>
@ -18,16 +53,46 @@
export default {
name: 'NavHeader',
props: {
//
dark: {
type: Boolean,
default: false
},
//
title: {
type: String,
default: ''
},
//
leftText: {
type: String,
default: ''
},
//
rightText: {
type: String,
default: ''
},
//
leftIcon: {
type: String,
default: ''
},
//
rightIcon: {
type: String,
default: ''
},
//
showBack: {
type: Boolean,
default: false
},
//
showBackText: {
type: Boolean,
default: false
},
//
backUrl: {
type: String,
@ -36,12 +101,12 @@ export default {
//
color: {
type: String,
default: '#000000'
default: ''
},
//
backgroundColor: {
type: String,
default: 'transparent'
default: ''
},
//
fixed: {
@ -53,15 +118,87 @@ export default {
type: Boolean,
default: true
},
//
border: {
//
shadow: {
type: Boolean,
default: false
},
//
height: {
type: [Number, String],
default: 44
},
//
leftWidth: {
type: [Number, String],
default: 60
},
//
rightWidth: {
type: [Number, String],
default: 60
}
},
data() {
return {
statusBarHeight: 20, //
innerTitle: '', // 使
navbarHeight: 44 //
}
},
computed: {
//
themeBgColor() {
if (this.dark) {
if (this.backgroundColor) {
return this.backgroundColor;
} else {
return this.dark ? '#333' : '#FFF';
}
}
return this.backgroundColor || '#FFF';
},
//
themeColor() {
if (this.dark) {
if (this.color) {
return this.color;
} else {
return this.dark ? '#fff' : '#333';
}
}
return this.color || '#333';
}
},
created() {
this.getStatusBarHeight();
this.innerTitle = this.title;
//
this.navbarHeight = typeof this.height === 'number' ? this.height : parseInt(this.height);
},
watch: {
title(newVal) {
this.innerTitle = newVal;
}
},
methods: {
//
getStatusBarHeight() {
uni.getSystemInfo({
success: (res) => {
this.statusBarHeight = res.statusBarHeight || 20;
}
});
},
//
goBack() {
this.onClickLeft();
},
//
onClickLeft() {
this.$emit('clickLeft');
if (this.backUrl) {
//
this.$router.navigateTo(this.backUrl, {}, 'redirectTo')
@ -85,18 +222,152 @@ export default {
this.$router.navigateTo('/pages/shouye/index', {}, 'switchTab');
}
}
},
//
onClickRight() {
this.$emit('clickRight');
},
//
onClickTitle() {
this.$emit('clickTitle');
}
}
}
</script>
<style lang="scss">
.nav-header {
&__back {
$nav-height: 44px;
.custom-nav-header {
/* 整体容器 */
width: 100%;
&__content {
/* 内容区 */
position: relative;
background-color: transparent;
}
&__status-bar {
/* 状态栏 */
height: 20px;
}
&__header {
/* 头部导航 */
display: flex;
flex-direction: row;
height: $nav-height;
padding: 0 10px;
font-size: 14px;
}
&__header-btns {
/* 按钮通用样式 */
display: flex;
flex-wrap: nowrap;
flex-direction: row;
width: 120rpx;
justify-content: center;
align-items: center;
}
&__header-btns-left {
/* 左侧按钮 */
display: flex;
justify-content: flex-start;
align-items: center;
}
&__header-btns-right {
/* 右侧按钮 */
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
}
&__header-container {
/* 标题容器 */
display: flex;
flex: 1;
padding: 0 10px;
overflow: hidden;
}
&__header-container-inner {
/* 标题内部容器 */
display: flex;
flex: 1;
flex-direction: row;
align-items: center;
justify-content: center;
font-size: 14px;
overflow: hidden;
}
&__icon {
/* 返回图标 */
width: 12px;
height: 12px;
border-left: 2px solid;
border-bottom: 2px solid;
transform: rotate(45deg);
}
&__content-view {
display: flex;
align-items: center;
height: 44px;
padding-left: 10px;
justify-content: center;
}
&__placeholder {
/* 占位符 */
width: 100%;
}
&__placeholder-view {
height: $nav-height;
}
/* 修饰样式 */
&--fixed {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 998;
}
&--shadow {
box-shadow: 0 1px 6px #ccc;
}
&--dark {
background-color: #333;
}
}
.custom-nav-header-btn-text {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
line-height: 12px;
}
.custom-nav-bar-text {
font-size: 16px;
font-weight: 500;
}
.custom-nav-bar-right-text {
font-size: 12px;
}
.custom-nav-ellipsis-1 {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>

View File

@ -1,9 +1,28 @@
<template>
<view class="page-container" :style="{ backgroundColor: backgroundColor }">
<nav-header :title="title" :showBack="showBack" :backUrl="backUrl" :color="navColor"
:backgroundColor="navBackgroundColor" :fixed="fixed" :statusBar="statusBar" :border="border">
<nav-header
:title="navTitle"
:showBack="showBack"
:backUrl="backUrl"
:color="navColor"
:backgroundColor="navBackgroundColor"
:fixed="fixed"
:statusBar="statusBar"
:shadow="shadow"
:dark="dark"
:height="navHeight"
:leftText="leftText"
:rightText="rightText"
:leftIcon="showBack ? 'back' : ''"
@clickLeft="onClickLeft"
@clickRight="onClickRight"
@clickTitle="onClickTitle">
<template #right>
<slot name="nav-right"></slot>
</template>
</nav-header>
<view class="page-container__content" :style="{ paddingBottom: paddingBottom }">
<view class="page-container__content" :style="contentStyle">
<view class="page-container__divider" v-if="divider"></view>
<slot></slot>
</view>
</view>
@ -17,17 +36,33 @@ export default {
components: {
NavHeader
},
emits: ['clickLeft', 'clickRight', 'clickTitle'],
props: {
//
title: {
type: String,
default: ''
},
//
dark: {
type: Boolean,
default: false
},
//
showBack: {
type: Boolean,
default: false
},
//
leftText: {
type: String,
default: ''
},
//
rightText: {
type: String,
default: ''
},
//
backUrl: {
type: String,
@ -58,16 +93,88 @@ export default {
type: Boolean,
default: true
},
//
border: {
//
shadow: {
type: Boolean,
default: false
},
// 线
divider: {
type: Boolean,
default: true
},
//
navHeight: {
type: [Number, String],
default: 44
},
//
paddingBottom: {
type: String,
default: '0px'
}
},
data() {
return {
statusBarHeight: 20, //
navbarHeight: 44, //
navTitle: '' // 使prop
}
},
computed: {
//
contentStyle() {
let style = {
'padding-bottom': this.paddingBottom
};
//
if (this.fixed) {
let paddingTop = this.statusBar ? (this.statusBarHeight + this.navbarHeight) : this.navbarHeight;
style['padding-top'] = paddingTop + 'px';
}
return style;
}
},
created() {
this.getStatusBarHeight();
//
this.navbarHeight = typeof this.navHeight === 'number' ? this.navHeight : parseInt(this.navHeight);
//
this.navTitle = this.title;
},
watch: {
// title
title(newVal) {
this.navTitle = newVal;
}
},
methods: {
//
getStatusBarHeight() {
uni.getSystemInfo({
success: (res) => {
this.statusBarHeight = res.statusBarHeight || 20;
}
});
},
//
onClickLeft() {
this.$emit('clickLeft');
},
//
onClickRight() {
this.$emit('clickRight');
},
//
onClickTitle() {
this.$emit('clickTitle');
},
//
setNavTitle(title) {
this.navTitle = title;
}
}
}
</script>
@ -81,6 +188,19 @@ export default {
&__content {
width: 100%;
box-sizing: border-box;
position: relative;
}
&__divider {
width: 100%;
height: 4rpx;
background-color: #e5e5e5; /* 使用较浅的灰色 */
position: relative;
top: 0;
left: 0;
right: 0;
z-index: 1;
margin-bottom: 10rpx; /* 在分割线下方添加一些间距 */
}
}
</style>

View File

@ -1,5 +1,5 @@
<template>
<page-container :title="title" :showBack="true">
<page-container ref="pageContainer" :title="title" :showBack="true">
<view class="content minHeight100">
<view class="header relative" v-if="pageData && pageData.goods"
:style="{ background: 'url(' + pageData.goods.imgurl_detail + ') no-repeat 0 0 / 100% 100%' }">
@ -713,6 +713,8 @@ export default {
})
if (res.data.goods.type_text) {
this.title = res.data.goods.type_text
// 使$refs访page-container
// this.$refs.pageContainer.setNavTitle(res.data.goods.type_text);
}
this.pageData = res.data
let goodType = this.$config.getGoodTypeFind(this.pageData.goods.type);