Files
medicine_app/uni_modules/z-nav-bar/components/z-nav-bar/z-nav-bar.vue
2024-06-20 17:04:17 +08:00

683 lines
17 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>
<view
:class="[
navFixed ? 'header_fixed' : '',
type == 'transparent' ? 'header_absolute' : '',
navShadow ? 'header_shadow' : '',
themeBgColorName,
]"
:style="[
navBgColor ? { backgroundImage: navBgColor } : {},
{
paddingTop: statusBarHeight + 'px',
color: navFontColor,
opacity: transparentValue,
},
]"
>
<view class="header_content">
<view class="header_left_box">
<slot name="left">
<view
class="header_left_info"
:class="[
isTwoBtn ? 'header_btnMongol' : '',
isWhite && isTwoBtn ? 'header_colorWhite_btnMongol' : '',
]"
v-if="back || $slots.left || home"
>
<view
class="header_left_back"
:class="[isTwoBtn ? 'header_btnMongol_left_back' : '']"
v-if="back && !firstPage"
@click="onBackPage"
>
<image
class="header_icon"
v-if="isWhite"
src="../../static/icon_back_white.png"
mode="aspectFit"
></image>
<image
class="header_icon"
v-else
src="../../static/icon_back_black.png"
mode="aspectFit"
>
</image>
</view>
<text
class="header_left_line"
:class="[isWhite ? 'header_colorWhite_left_line' : '']"
v-if="isTwoBtn"
></text>
<view
class="header_left_home"
:class="[isTwoBtn ? 'header_btnMongol_left_home' : '']"
v-if="(firstPage && back) || home"
@click="onBackHome"
>
<image
class="header_icon"
v-if="isWhite"
src="../../static/icon_home_white.png"
mode="aspectFit"
></image>
<image
class="header_icon"
v-else
src="../../static/icon_home_black.png"
mode="aspectFit"
>
</image>
</view>
</view>
</slot>
<view
class="header_title"
v-if="!titleCenter && ($slots.default || navTitle)"
:style="{ color: navFontColor }"
>
<slot>
<text :style="{ color: navFontColor }">{{ navTitle }}</text>
</slot>
</view>
</view>
<view
class="header_title header_title_center"
v-if="titleCenter && ($slots.default || navTitle)"
:style="{ color: navFontColor }"
>
<slot>
<text :style="{ color: navFontColor }">{{ navTitle }}</text>
</slot>
</view>
<view class="header_right_info">
<slot name="right"></slot>
</view>
</view>
</view>
<view
class="header_transparentFixed header_fixed"
v-if="type == 'transparentFixed'"
:style="{
paddingTop: statusBarHeight + 'px',
color: navTransparentFixedFontColor,
opacity: 1 - transparentValue,
zIndex: transparentValue < 0.3 ? 100 : 90,
}"
>
<view class="header_content">
<view class="header_left_box">
<slot name="transparentFixedLeft">
<view
class="header_left_info header_transparentFixed_left_info"
:class="[
isWhite ? 'header_transparentFixed_colorWhite_left_info' : '',
]"
v-if="back || $slots.left || home"
>
<view
class="header_left_back"
:class="[isTwoBtn ? 'header_btnMongol_left_back' : '']"
v-if="back && !firstPage"
@click="onBackPage"
>
<image
class="header_icon"
v-if="isWhite"
src="../../static/icon_back_white.png"
mode="aspectFit"
></image>
<image
class="header_icon"
v-else
src="../../static/icon_back_black.png"
mode="aspectFit"
>
</image>
</view>
<text class="header_left_line" v-if="isTwoBtn"></text>
<view
class="header_left_home"
:class="[isTwoBtn ? 'header_btnMongol_left_home' : '']"
v-if="(firstPage && back) || home"
@click="onBackHome"
>
<image
class="header_icon"
v-if="isWhite"
src="../../static/icon_home_white.png"
mode="aspectFit"
></image>
<image
class="header_icon"
v-else
src="../../static/icon_home_black.png"
mode="aspectFit"
>
</image>
</view>
</view>
</slot>
<view
class="header_title"
v-if="!titleCenter && (navTitle || $slots.transparentFixed)"
:style="{ color: navTransparentFixedFontColor }"
>
<slot name="transparentFixed">
<text :style="{ color: navTransparentFixedFontColor }">{{
navTitle
}}</text>
</slot>
</view>
</view>
<view
class="header_title header_title_center"
v-if="titleCenter && (navTitle || $slots.transparentFixed)"
:style="{ color: navTransparentFixedFontColor }"
>
<slot name="transparentFixed">
<text :style="{ color: navTransparentFixedFontColor }">{{
navTitle
}}</text>
</slot>
</view>
<view class="header_right_info">
<slot name="transparentFixedRight"></slot>
</view>
</view>
</view>
<view
v-if="type == 'fixed'"
:style="{ paddingTop: statusBarHeight + 'px' }"
>
<view class="header_station"></view>
</view>
</view>
</template>
<script>
import { mainPagePath, homePath } from "@/config/componentConfig";
//白色表达值
const whiteList = [
"#FFF",
"#fff",
"#FFFFFF",
"#ffffff",
"white",
"rgb(255,255,255)",
"rgba(255,255,255,1)",
];
export default {
props: {
//是否显示返回按钮
// 1000 显示返回按钮
// 2000 不显示返回按钮
// 3000 自定义返回按钮方法点击返回箭头后会发送一个backClick事件
backState: {
type: [String, Number],
default: function () {
return 1000;
},
},
//是否显示返回首页按钮
// 1000 显示首页按钮
// 2000 不显示首页按钮
// 3000 自定义首页按钮方法点击首页箭头后会发送一个homeClick事件
homeState: {
type: [String, Number],
default: function () {
return 2000;
},
},
//导航背景色,支持渐变
bgColor: {
type: [String, Array],
default: function () {
return "#FFFFFF";
},
},
// 导航背景色渐变角度
bgColorAngle: {
type: [String, Number],
default: function () {
return 90;
},
},
//导航字体颜色,字体颜色为白色的时候会把手机状态栏设置为白色,否则为黑色
fontColor: {
type: String,
default: function () {
return "#000000";
},
},
navFontAlign: {
type: String,
default: function () {
return "center";
},
},
//标题是否居中
titleCenter: {
type: Boolean,
default: function () {
return true;
},
},
//标题
title: {
type: String,
default: function () {
return "";
},
},
//类型 fixed为固定 默认
// ordinary 普通的 不固定
// transparent 透明不固定的
//transparentFixed 透明固定的
type: {
type: String,
default: function () {
return "fixed";
},
},
//透明固定的时候字体颜色
transparentFixedFontColor: {
type: String,
default: function () {
return "#000000";
},
},
// 屏幕滑动距离顶部距离(透明固定导航比传)
scrollTop: {
type: Number,
default: function () {
return 0;
},
},
// 是否显示阴影
shadow: {
type: Boolean,
default: function () {
return false;
},
},
},
data() {
return {
//当前页面是否是第一个页面
firstPage: false,
//透明度值
transparentValue: 1,
//标题
navTitle: "",
//字体色
navFontColor: "#000000",
//背景色
navBgColor: "",
//透明底字体色
navTransparentFixedFontColor: "#000000",
// 导航栏高度
statusBarHeight: 0,
// 上次显示的导航栏颜色
lastFrontColor: "",
themeBgColorName: "",
};
},
computed: {
back() {
return this.backState == 1000 || this.backState == 3000;
},
home() {
return this.homeState == 1000;
},
//导航固定
navFixed() {
if (this.type == "transparentFixed" || this.type == "fixed") {
return true;
} else {
return false;
}
},
//导航底部线是否显示
navShadow() {
if (this.bgColor && typeof this.bgColor == "string") {
return (
this.shadow &&
this.type !== "transparent" &&
whiteList.includes(this.bgColor)
);
} else {
return false;
}
},
//导航字体是否是白色颜色
isWhite() {
// console.log(whiteList,'this.navFontColor')
return whiteList.includes(this.navFontColor);
},
//右上角是否有两个按钮
isTwoBtn() {
return (
(this.backState == 1000 || this.backState == 3000) &&
this.homeState == 1000 &&
!this.firstPage
);
},
},
watch: {
title(val) {
this.navTitle = val;
},
fontColor(val) {
this.navFontColor = val;
this.settingColor();
},
bgColor(val) {
this.getNavBgColor(val);
},
transparentFixedFontColor(val) {
this.navTransparentFixedFontColor = val;
},
scrollTop(val) {
this.pageScroll({
scrollTop: val,
});
},
},
//第一次加载
created() {
this.navTitle = this.title;
this.navFontColor = this.fontColor;
this.getNavBgColor(this.bgColor);
this.navTransparentFixedFontColor = this.transparentFixedFontColor;
//获取手机状态栏高度
this.statusBarHeight = uni.getSystemInfoSync()["statusBarHeight"];
const _this = this;
this.pageScroll({
scrollTop: this.scrollTop,
});
//获取所有页面
let currentPages = getCurrentPages();
let pageLen = currentPages.length;
//判断是否是第一个页面如果是有设置back为true的页面将不显示返回箭头而显示返回首页按钮
// if (pageLen == 1 && !mainPagePath.includes(currentPages[0].route)) {
// this.firstPage = true;
// }
},
//方法
methods: {
//返回上一页面
onBackPage() {
if (this.backState == 3000) {
this.$emit("backClick");
} else {
uni.navigateBack();
}
},
//返回首页
onBackHome() {
if (this.homeState == 3000) {
this.$emit("homeClick");
} else {
uni.switchTab({
url: '/pages/homePage/index/index',
});
}
},
pageScroll(e) {
if (this.type == "transparentFixed") {
if (e.scrollTop && e.scrollTop > 0) {
if (e.scrollTop > 180) {
this.transparentValue = 1;
} else {
this.transparentValue = e.scrollTop / 180;
}
} else {
this.transparentValue = 0;
}
this.settingColor();
}
},
// 获取导航背景颜色
getNavBgColor(val) {
if (typeof val == "string") {
if (this.type == "transparent") {
this.navBgColor = "";
} else if (/^#|rgb\(|rgba\(/.test(val)) {
this.navBgColor = "linear-gradient(90deg," + val + "," + val + ")";
} else {
this.themeBgColorName = val;
this.navBgColor = "";
}
} else if (Array.isArray(val) && val.length >= 2) {
let navBgColor = "linear-gradient(" + this.bgColorAngle + "deg";
val.forEach((item) => {
if (typeof item == "string") {
navBgColor += "," + item;
} else if (typeof item == "object") {
navBgColor += "," + item.color + " " + item.scale;
}
});
navBgColor += ")";
this.navBgColor = navBgColor;
}
},
//设置手机状态栏颜色
settingColor() {
let navColor = this.navFontColor;
if (this.type == "transparentFixed" && this.transparentValue <= 0.5) {
navColor = this.navTransparentFixedFontColor;
}
let frontColor = "#000000";
if (whiteList.includes(navColor)) {
frontColor = "#ffffff";
}
if (this.lastFrontColor == frontColor) {
return;
}
setTimeout(() => {
this.lastFrontColor = frontColor;
// 改变手机状态栏颜色
uni.setNavigationBarColor({
frontColor: frontColor,
backgroundColor: "#FFFFFF",
});
}, 150);
},
},
};
</script>
<style lang="scss">
.header_content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
/* #ifdef MP */
padding-right: 190rpx;
box-sizing: border-box;
/* #endif */
width: 750rpx;
align-items: flex-end;
justify-content: space-between;
flex-direction: row;
height: 88rpx;
position: relative;
}
.header_station {
height: 88rpx;
}
.header_shadow {
// border-style: solid;
// border-width: 2rpx;
// border-color: #f5f5f5;
box-shadow: 0 0 6rpx 0 #ddd;
}
.header_fixed {
position: fixed;
top: 0;
left: 0;
width: 750rpx;
z-index: 99;
}
.header_absolute {
position: absolute;
top: 0;
left: 0;
z-index: 99;
width: 750rpx;
background-color: transparent !important;
}
.header_left_box {
/* #ifndef APP-PLUS-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
height: 88rpx;
flex: 1;
}
.header_left_line {
height: 30rpx;
width: 2rpx;
background-color: rgba(255, 255, 255, 0.4);
}
.header_left_back {
width: 56rpx;
height: 100%;
/* #ifndef APP-PLUS-NVUE */
display: flex;
/* #endif */
align-items: center;
justify-content: center;
}
.header_icon {
width: 30rpx;
height: 30rpx;
}
.header_left_home {
width: 56rpx;
height: 100%;
/* #ifndef APP-PLUS-NVUE */
display: flex;
/* #endif */
align-items: center;
justify-content: center;
}
.header_left_info {
/* #ifndef APP-PLUS-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
height: 56rpx;
margin-left: 16rpx;
}
.header_title {
height: 88rpx;
font-size: 32rpx;
padding-left: 30rpx;
padding-right: 30rpx;
font-weight: 700;
text-overflow: ellipsis;
/* #ifndef APP-PLUS-NVUE */
white-space: nowrap;
display: flex;
overflow: hidden;
/* #endif */
/* #ifdef APP-PLUS-NVUE */
lines: 1;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
/* #ifdef MP */
max-width: calc(100vw - 160rpx);
/* #endif */
}
.header_title_center {
position: absolute;
bottom: 0rpx;
left: 375rpx;
transform: translateX(-50%);
}
.header_right_info {
height: 88rpx;
/* #ifndef APP-PLUS-NVUE */
display: flex;
flex-shrink: 0;
/* #endif */
flex-direction: row;
align-items: center;
}
.header_btnMongol {
border-radius: 33rpx;
border-style: solid;
border-width: 2rpx;
border-color: rgba(0, 0, 0, 0.1);
background-color: rgba(255, 255, 255, 0.7);
/* #ifndef APP-PLUS-NVUE */
box-sizing: border-box;
/* #endif */
}
.header_btnMongol_left_back,
.header_btnMongol_left_home {
width: 70rpx;
}
.header_transparentFixed {
border-bottom-width: 0;
background-color: transparent;
background-image: transparent;
}
.header_transparentFixed_left_info {
border-style: solid;
border-width: 2rpx;
border-color: rgba(0, 0, 0, 0.1);
background-color: rgba(255, 255, 255, 0.7);
border-radius: 33rpx;
/* #ifndef APP-PLUS-NVUE */
box-sizing: border-box;
/* #endif */
}
.header_transparentFixed_colorWhite_left_info {
border-style: solid;
border-width: 2rpx;
border-color: rgba(255, 255, 255, 0.3);
background-color: rgba(0, 0, 0, 0.2);
}
//颜色白色
.header_colorWhite_btnMongol {
border-style: solid;
border-width: 2rpx;
border-color: rgba(255, 255, 255, 0.3);
background-color: rgba(0, 0, 0, 0.2);
}
.header_colorWhite_left_line {
background-color: rgba(255, 255, 255, 0.3);
}
</style>