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.
504 lines
12 KiB
504 lines
12 KiB
<template>
|
|
<view class="niu-navbar">
|
|
<view class="niu-navbar__status" v-if="status" :style="{
|
|
position: toShow&&block?'':'relative',
|
|
backgroundColor: gradient?gradient:statusColor?statusColor:'',
|
|
height: x_statusHeight?(x_statusHeight+'px'):''
|
|
}"></view>
|
|
<view class="niu-navbar__block"
|
|
:style="{height: x_height?(x_height+'px'):'',paddingTop: x_statusHeight?(x_statusHeight+'px'):''}"
|
|
v-if="toShow&&toFixed&&block"></view>
|
|
<view class="niu-navbar__wrapper" v-if="toShow" :style="{
|
|
height: x_height?(x_height+'px'):'',
|
|
paddingTop: x_statusHeight?(x_statusHeight+'px'):'',
|
|
top: x_statusHeight?(0+'px'):'',
|
|
opacity:x_opacity,
|
|
backgroundImage: gradient?gradient:'',
|
|
backgroundColor: !gradient?bg:'transparent'
|
|
}" :class="[toFixed?'fixed':'',border?'border':'']">
|
|
<view v-if="!oneline" class="niu-navbar__left" @click="clickLeft"
|
|
:style="{color: color,height: x_height?(x_height+'px'):'',lineHeight: x_height?(x_height+'px'):'',top: x_statusHeight?(x_statusHeight+'px'):''}">
|
|
<slot name="left">
|
|
<!-- <i v-if="back" class="niu-navbar__icon iconfont icon-back_light"></i> -->
|
|
<image v-if="!firstPage&&back" class="niu-navbar__icon"
|
|
src="https://shidaizhu.oss-cn-shenzhen.aliyuncs.com/app_static/icons/icon3.png" mode=""></image>
|
|
<text v-if="!firstPage&&back&&leftText" class="niu-navbar__text">{{leftText}}</text>
|
|
</slot>
|
|
</view>
|
|
<!-- ,marginRight: adjust?(x_width+'px'):'' -->
|
|
<view v-if="!oneline" class="niu-navbar__middle"
|
|
:class="{center:middleLayout=='center',left:middleLayout=='left'}"
|
|
:style="{ color: color,top: x_statusHeight?(x_statusHeight+'px'):'',height: x_height?(x_height+'px'):'',lineHeight: x_height?(x_height+'px'):'' }">
|
|
<slot></slot>
|
|
</view>
|
|
<view v-if="!oneline" class="niu-navbar__right"
|
|
:style="{color: color,height: x_height?(x_height+'px'):'',lineHeight: x_height?(x_height+'px'):'',top: x_statusHeight?(x_statusHeight+'px'):'',marginRight: adjust?(x_width+'px'):''}">
|
|
<slot name="right"></slot>
|
|
</view>
|
|
<view v-if="oneline" class="niu-navbar__middle"
|
|
:class="{center:middleLayout=='center',left:middleLayout=='left'}"
|
|
:style="{ color: color,top: x_statusHeight?(x_statusHeight+'px'):'',height: x_height?(x_height+'px'):'',lineHeight: x_height?(x_height+'px'):'',marginRight: adjust?(x_width+'px'):'' }">
|
|
<slot></slot>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
let mainPagePath = "pages/index/index"
|
|
const _throttle = function(fn, interval) {
|
|
var last;
|
|
var timer;
|
|
var interval = interval || 200;
|
|
return function() {
|
|
var th = this;
|
|
var args = arguments;
|
|
var now = +new Date();
|
|
if (last && now - last < interval) {
|
|
clearTimeout(timer);
|
|
timer = setTimeout(function() {
|
|
last = now;
|
|
fn.apply(th, args);
|
|
}, interval);
|
|
} else {
|
|
last = now;
|
|
fn.apply(th, args);
|
|
}
|
|
}
|
|
}
|
|
export default {
|
|
props: {
|
|
oneline: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
gradient: {
|
|
type: String,
|
|
default: ""
|
|
},
|
|
middleLayout: {
|
|
type: String,
|
|
default: "center"
|
|
},
|
|
adjust: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
color: {
|
|
type: String,
|
|
default: "#000"
|
|
},
|
|
bg: {
|
|
type: String,
|
|
default: ""
|
|
},
|
|
border: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
leftText: {
|
|
type: String,
|
|
default: ""
|
|
},
|
|
back: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
status: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
statusColor: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
/**
|
|
* 是否显示
|
|
*/
|
|
show: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
/**
|
|
* 是否吸顶
|
|
*/
|
|
fixed: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
/**
|
|
* 是否强制吸顶
|
|
*/
|
|
forceFixed: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
/**
|
|
* 非强制吸顶+吸顶:偏移这么多之后吸顶
|
|
*/
|
|
offset: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
/**
|
|
* 强制吸顶+吸顶:渐隐的距离
|
|
*/
|
|
opacityOffset: {
|
|
type: Number,
|
|
default: 400
|
|
},
|
|
/**
|
|
* 强制吸顶+吸顶+渐隐:
|
|
*/
|
|
offsetHideOpacity: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
/**
|
|
* 强制吸顶+吸顶:是否渐隐
|
|
*/
|
|
offsetHide: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
/**
|
|
* 是否需要占位块
|
|
*/
|
|
block: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
},
|
|
beforeDestroy() {
|
|
// #ifdef H5
|
|
window.removeEventListener("scroll", this.scroll)
|
|
// #endif
|
|
},
|
|
created() {
|
|
// #ifdef MP
|
|
let statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
|
|
let menuButtonInfo = uni.getMenuButtonBoundingClientRect()
|
|
this.x_statusHeight = statusBarHeight
|
|
this.x_height = (menuButtonInfo.top - statusBarHeight) * 2 + menuButtonInfo.height;
|
|
this.x_width = menuButtonInfo.width + 10
|
|
// #endif
|
|
// #ifdef APP-PLUS
|
|
let statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
|
|
this.x_statusHeight = statusBarHeight
|
|
// #endif
|
|
},
|
|
mounted() {
|
|
let pages = getCurrentPages();
|
|
if (pages.length == 1 && mainPagePath.includes(pages[0].route)) {
|
|
this.firstPage = true;
|
|
}
|
|
this.$n.$obs.setTop(this.getNavbarHeight())
|
|
// #ifdef H5
|
|
window.addEventListener("scroll", this.scroll, false)
|
|
// #endif
|
|
// #ifndef H5
|
|
if (pages.length) {
|
|
let that = this;
|
|
let onPageScroll = pages[pages.length - 1].onPageScroll;
|
|
pages[pages.length - 1].onPageScroll = function(e) {
|
|
onPageScroll.call(this, e);
|
|
that.$emit('scroll', e);
|
|
that.scroll(e);
|
|
};
|
|
}
|
|
// #endif
|
|
},
|
|
computed: {
|
|
toFixed() {
|
|
return this.fixed && this.x_fixed
|
|
},
|
|
toShow() {
|
|
return this.show && this.x_show
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
firstPage: false,
|
|
x_height: 0,
|
|
x_width: 0,
|
|
x_statusHeight: 0,
|
|
x_show: true,
|
|
x_fixed: this.fixed,
|
|
x_opacity: 1,
|
|
};
|
|
},
|
|
methods: {
|
|
statusBarHeight(isPx = false) {
|
|
let height = uni.getSystemInfoSync().statusBarHeight
|
|
return isPx ? height + 'px' : height;
|
|
},
|
|
getNavbarHeight(isPx = false) {
|
|
let height = uni.upx2px(88);
|
|
let statusBarHeight = this.statusBarHeight();
|
|
// #ifdef MP
|
|
let menuButtonInfo = uni.getMenuButtonBoundingClientRect()
|
|
height = (menuButtonInfo.top - statusBarHeight) * 2 + menuButtonInfo.height;
|
|
height = height + statusBarHeight;
|
|
// #endif
|
|
// #ifdef APP-PLUS
|
|
height = height + statusBarHeight;
|
|
// #endif
|
|
return isPx ? height + 'px' : height;
|
|
},
|
|
clickLeft(e) {
|
|
if (this.back) {
|
|
// #ifdef H5
|
|
history.back()
|
|
// #endif
|
|
// #ifndef H5
|
|
uni.navigateBack({
|
|
delta: 1
|
|
})
|
|
// #endif
|
|
}
|
|
this.$emit("clickLeft", e)
|
|
},
|
|
scroll(e) {
|
|
// #ifdef H5
|
|
let scrollTop = document.documentElement.scrollTop
|
|
// #endif
|
|
// #ifndef H5
|
|
let scrollTop = e.scrollTop;
|
|
// #endif
|
|
const navHeight = uni.upx2px(92);
|
|
if (!this.forceFixed) {
|
|
if (this.offset < navHeight) {
|
|
this.x_fixed = true;
|
|
} else {
|
|
if (navHeight <= (scrollTop - this.offset)) {
|
|
this.x_fixed = true;
|
|
} else {
|
|
this.x_fixed = false;
|
|
|
|
}
|
|
}
|
|
} else {
|
|
if (this.offsetHide && this.opacityOffset >= uni.upx2px(92) * 2) {
|
|
if (!this.x_show) {
|
|
scrollTop = scrollTop + navHeight + 20;
|
|
}
|
|
let opacity = ~~((this.opacityOffset - scrollTop) / this.opacityOffset * 1000);
|
|
opacity = opacity > 1000 ? 1000 : opacity;
|
|
opacity = opacity < this.offsetHideOpacity ? 0 : opacity;
|
|
this.x_opacity = opacity / 1000;
|
|
if (this.x_opacity <= 0) {
|
|
this.x_show = false
|
|
} else {
|
|
this.x_show = true
|
|
}
|
|
} else {
|
|
this.x_show = true
|
|
}
|
|
}
|
|
|
|
},
|
|
// scroll: _throttle(async function(e) {
|
|
// // #ifdef H5
|
|
// let scrollTop = document.documentElement.scrollTop
|
|
// // #endif
|
|
// // #ifndef H5
|
|
// let scrollTop = e.scrollTop;
|
|
// // #endif
|
|
// const navHeight = uni.upx2px(92);
|
|
// if (!this.forceFixed) {
|
|
// if (this.offset < navHeight) {
|
|
// this.x_fixed = true;
|
|
// } else {
|
|
// if (navHeight <= (scrollTop - this.offset)) {
|
|
// this.x_fixed = true;
|
|
// } else {
|
|
// this.x_fixed = false;
|
|
|
|
// }
|
|
// }
|
|
// } else {
|
|
// if (this.offsetHide && this.opacityOffset >= uni.upx2px(92) * 2) {
|
|
// if (!this.x_show) {
|
|
// scrollTop = scrollTop + navHeight + 20;
|
|
// }
|
|
// let opacity = ~~((this.opacityOffset - scrollTop) / this.opacityOffset * 1000);
|
|
// opacity = opacity > 1000 ? 1000 : opacity;
|
|
// opacity = opacity < this.offsetHideOpacity ? 0 : opacity;
|
|
// this.x_opacity = opacity / 1000;
|
|
// if (this.x_opacity <= 0) {
|
|
// this.x_show = false
|
|
// } else {
|
|
// this.x_show = true
|
|
// }
|
|
// } else {
|
|
// this.x_show = true
|
|
// }
|
|
// }
|
|
// }, 0)
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
$name: niu-navbar;
|
|
$height: 88rpx;
|
|
|
|
// @mixin hairline {
|
|
// position: relative;
|
|
|
|
// &::after {
|
|
// position: absolute;
|
|
// box-sizing: border-box;
|
|
// content: " ";
|
|
// pointer-events: none;
|
|
// top: -50%;
|
|
// right: -50%;
|
|
// bottom: -50%;
|
|
// left: -50%;
|
|
// border: 0 solid #ebedf0;
|
|
// -webkit-transform: scale(0.5);
|
|
// transform: scale(0.5);
|
|
// @content
|
|
// }
|
|
// }
|
|
|
|
// @mixin hairline--bottom {
|
|
// @include hairline {
|
|
// border-bottom-width: 1px;
|
|
// }
|
|
// }
|
|
|
|
.niu-navbar {
|
|
position: relative;
|
|
z-index: 99;
|
|
box-sizing: content-box;
|
|
|
|
&__status {
|
|
box-sizing: content-box;
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: var(--status-bar-height);
|
|
background-color: transparent;
|
|
z-index: 999;
|
|
}
|
|
|
|
&__block {
|
|
box-sizing: content-box;
|
|
// position: relative;
|
|
padding-top: var(--status-bar-height);
|
|
height: $height;
|
|
// background-color: red;
|
|
// z-index: 9999999;
|
|
}
|
|
|
|
&__wrapper {
|
|
// padding-top: var(--status-bar-height);
|
|
box-sizing: content-box;
|
|
|
|
&.fixed {
|
|
box-sizing: content-box;
|
|
position: fixed;
|
|
top: var(--status-bar-height);
|
|
// top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
}
|
|
|
|
z-index: 999;
|
|
position: relative;
|
|
background-color: white;
|
|
width: 750rpx;
|
|
height: $height;
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
&.border {
|
|
@include hairline--bottom;
|
|
}
|
|
|
|
font-size: 29rpx;
|
|
|
|
.#{$name}__left {
|
|
box-sizing: content-box;
|
|
padding: 0 20rpx;
|
|
width: 150rpx;
|
|
// position: absolute;
|
|
// left: 0;
|
|
// top: 0;//var(--status-bar-height);
|
|
display: flex;
|
|
align-items: center;
|
|
// cursor: pointer;
|
|
font-size: 28rpx;
|
|
height: $height;
|
|
|
|
// line-height: 1.5;
|
|
.#{$name}__icon {
|
|
box-sizing: content-box;
|
|
margin-right: 8rpx;
|
|
vertical-align: middle;
|
|
line-height: 1.5;
|
|
width: 25rpx;
|
|
height: 28rpx;
|
|
}
|
|
|
|
.#{$name}__text {
|
|
box-sizing: content-box;
|
|
flex: 1;
|
|
width: 0;
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
line-height: 1.2;
|
|
margin-left: 20rpx;
|
|
vertical-align: middle;
|
|
white-space: nowrap;
|
|
}
|
|
}
|
|
|
|
.#{$name}__middle {
|
|
box-sizing: content-box;
|
|
white-space: nowrap;
|
|
text-align: center;
|
|
// position: absolute;
|
|
font-size: 32rpx;
|
|
font-weight: 600;
|
|
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
&.center {
|
|
justify-content: center;
|
|
}
|
|
|
|
&.left {
|
|
justify-content: flex-start;
|
|
}
|
|
|
|
// justify-content: center;
|
|
height: $height;
|
|
line-height: $height;
|
|
flex: 1;
|
|
width: 0;
|
|
// right: 90rpx;
|
|
// left: 90rpx;
|
|
// top: 0;//var(--status-bar-height);
|
|
}
|
|
|
|
.#{$name}__right {
|
|
box-sizing: content-box;
|
|
width: 100rpx;
|
|
padding: 0 20rpx;
|
|
// position: absolute;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-end;
|
|
// right: 0;
|
|
height: $height;
|
|
width: 150rpx;
|
|
// top: 0;//var(--status-bar-height);
|
|
// cursor: pointer;
|
|
}
|
|
}
|
|
}
|
|
</style>
|
|
|