f-navbar.vue
9.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
<template>
<view class="f-navbar">
<view
:class="[navbarType == 1 ? 'f-relative' : 'f-fixed']"
:style="[navbarType == 1 ? { height: systemInfo.navBarH + 'px' } : { paddingTop: systemInfo.statusBarHeight + 'px' }]"
>
<!-- 背景色 -->
<view class="bgColor" :style="{ height: systemInfo.navBarH + 'px', background: bgColor, backgroundImage: gradient, opacity: navbarType == 5 ? transparentValue : '' }">
<image :src="image" :mode="imageMode" style="width: 750rpx;" :style="{ height: systemInfo.navBarH + 'px' }" v-if="image"></image>
</view>
<view class="u-flex content" :style="{ height: systemInfo.titleBarHeight + 'px', top: systemInfo.statusBarHeight + 'px' }">
<block v-if="navbarType != 4 && isShowLeft">
<view class="u-flex left" hover-class="left--hover" hover-start-time="150" v-if="navbarType == 3">
<view class="u-flex u-home-arrow-left" :style="{ borderColor: isWhite ? 'rgba(255,255,255,.5)' : '#dadbde' }">
<view @click="onBack"><u-icon name="arrow-left" size="19" :color="leftColor"></u-icon></view>
<u-line direction="column" :hairline="false" length="16" margin="0 8px" :color="isWhite ? 'rgba(255,255,255,.3)' : '#dadbde'"></u-line>
<view @click="onHome"><u-icon name="home" size="20" :color="leftColor"></u-icon></view>
</view>
</view>
<view class="u-flex left" hover-class="left--hover" hover-start-time="150" @click="leftClick" v-else>
<slot name="left">
<!-- 左边箭头背景渐变 -->
<view
class="iconBg u-flex"
:style="{ background: 'rgba(0,0,0,' + (navbarType == 5 ? (1 - transparentValue > 0.4 ? 0.4 : 1 - transparentValue) : 0) + ')' }"
>
<u-icon :name="iconLeft" size="16" :color="leftColor"></u-icon>
</view>
<text v-if="leftText" class="left__text" :style="{ color: leftColor }">{{ leftText }}</text>
</slot>
</view>
</block>
<view class="center" :style="{ width: titleWidth + 'rpx' }">
<slot name="default">
<view
class="title u-line-1"
:style="[
isShowTransparentTitle ? {} : { opacity: navbarType == 5 ? transparentValue : '' },
{ color: fontColor, width: titleWidth + 'rpx', fontSize: fontSize + 'rpx' }
]"
>
{{ title }}
</view>
</slot>
</view>
<view class="u-flex right" @click="rightClick"><slot name="right"></slot></view>
</view>
</view>
<!-- 防止塌陷高度 -->
<view v-if="isFillHeight && navbarType != 5 && navbarType != 1" :style="{ height: systemInfo.navBarH + 'px' }"></view>
</view>
</template>
<script>
// 主页页面的页面路径
// 关联功能:打开的页面只有一个的时候右上角自动显示返回首页按钮,下面这个数组是排除显示返回首页的页面。
// 主页使用场景:小程序分享出去的页面,用户点击开是分享页面,很多情况下是没有返回首页按钮的
const mainPagePath = ['pages/index/index', 'pages/device/device', 'pages/alarm/alarm', 'pages/personal/personal'];
//返回首页的地址
const homePath = '/pages/index/index';
//白色表达值
const whiteList = ['#FFF', '#fff', '#FFFFFF', '#ffffff', 'white', 'rgb(255,255,255)', 'rgba(255,255,255,1)'];
// import base from '@/config/baseUrl.js';
export default {
name: 'f-navbar',
props: {
title: {
type: String
},
// navbarType等于5透明背景时title是否显示
isShowTransparentTitle: {
type: Boolean,
default: function() {
return true;
}
},
// 左边文字
leftText: {
type: String
},
// 背景颜色
bgColor: {
type: String,
default: '#fff'
},
// 背景图片
image: {
type: String
},
// 背景图片mode
imageMode: {
type: String,
default: 'aspectFill'
},
// 导航状态 0、默认固定在顶部 1、不固定在顶部 2、自定义点击事件 3、同时显示箭头和去首页按钮 4、不显示左侧内容 5、上拉渐变显示背景色
navbarType: {
type: [String, Number],
default: 0
},
// 是否显示左侧内容
isShowLeft: {
type: Boolean,
default: function() {
return true;
}
},
// 左边按钮icon
leftIcon: {
type: String,
default: 'arrow-left'
},
// 左边icon颜色
leftIconColor: {
type: String,
default: '#303133'
},
// 屏幕滑动距离顶部距离(透明固定导航比传)
scrollTop: {
type: Number,
default: 0
},
//导航字体颜色,字体颜色为白色的时候会把手机状态栏设置为白色,否则为黑色
fontColor: {
type: String,
default: '#303133'
},
titleWidth: {
type: [String, Number],
default: 400
},
fontSize: {
type: [String, Number],
default: 30
},
gradient: {
type: String
},
// 是否设置防止塌陷高度
isFillHeight: {
type: Boolean,
default: function() {
return true;
}
}
},
data() {
return {
// systemInfo:base.systemInfo,
systemInfo: {
statusBarHeight: uni.getSystemInfoSync().statusBarHeight,
// #ifdef MP-ALIPAY
navBarH: uni.getSystemInfoSync().statusBarHeight + uni.getSystemInfoSync().titleBarHeight, //菜单栏总高度--单位px
titleBarHeight: uni.getSystemInfoSync().titleBarHeight, //标题栏高度--单位px
// #endif
// #ifndef MP-ALIPAY
navBarH: uni.getSystemInfoSync().statusBarHeight + 35, //菜单栏总高度--单位px
titleBarHeight: 35 //标题栏高度--单位px
// #endif
},
//当前页面是否是第一个页面
firstPage: false,
//透明度值
transparentValue: 0,
iconLeft: 'arrow-left', //左边icon
// 上次显示的导航栏颜色
lastFrontColor: '',
//字体色
navFontColor: '#303133',
isWhite: false //是否白色
};
},
watch: {
leftIcon: {
immediate: true,
handler(val) {
this.iconLeft = val;
}
},
fontColor: {
immediate: true,
handler(val) {
this.navFontColor = val;
this.settingColor();
}
},
navbarType: {
immediate: true,
handler(val) {
console.log(val, 'navbarType');
if (val == 5) {
if (this.scrollTop > 180) {
this.transparentValue = 1;
} else {
this.transparentValue = this.scrollTop / 180;
}
}
}
},
scrollTop(val) {
this.pageScroll({
scrollTop: val
});
}
},
computed: {
leftColor() {
let color = '#303133';
if (this.leftIconColor == '#303133') {
//如果等于默认值
// 背景不是白色或者背景是渐变色
if (!whiteList.includes(this.bgColor) || this.gradient) {
color = '#fff';
}
} else {
color = this.leftIconColor;
}
return color;
}
},
created() {
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;
this.iconLeft = 'home';
}
},
methods: {
onBack() {
if (this.firstPage) {
uni.reLaunch({
url: homePath
});
} else {
uni.navigateBack();
}
},
onHome() {
uni.switchTab({
url: homePath
});
},
leftClick() {
if (this.navbarType == 2) {
this.$emit('leftClick');
} else {
this.onBack();
}
},
rightClick() {
this.$emit('rightClick');
},
pageScroll(e) {
if (this.navbarType == 5) {
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();
}
},
//设置手机状态栏颜色
settingColor() {
let navColor = this.navFontColor;
let frontColor = '#000000';
if (whiteList.includes(navColor)) {
frontColor = '#ffffff';
this.isWhite = true;
}
if (this.lastFrontColor == frontColor) {
return;
}
setTimeout(() => {
this.lastFrontColor = frontColor;
// 改变手机状态栏颜色
// #ifndef MP-ALIPAY
uni.setNavigationBarColor({
frontColor: frontColor,
backgroundColor: '#FFFFFF'
});
// #endif
// #ifdef MP-ALIPAY
uni.setNavigationBarColor({
backgroundColor: frontColor == '#000000' ? '#ffffff' : '#000000'
});
// #endif
}, 150);
}
}
};
</script>
<style scoped lang="scss">
.u-flex {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
}
.f-navbar {
width: 750rpx;
.f-fixed {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
}
.f-relative {
position: relative;
}
.bgColor {
position: absolute;
top: 0;
left: 0;
right: 0;
}
.content {
position: absolute;
top: 0;
left: 0;
right: 0;
}
.title {
text-align: center;
color: #303133;
}
.center {
margin: 0 auto;
}
.left,
.right {
padding: 0 24rpx;
position: absolute;
top: 0;
bottom: 0;
}
.left {
left: 0;
&--hover {
opacity: 0.7;
}
&__text {
font-size: 30rpx;
margin-left: 3px;
}
.iconBg {
width: 50rpx;
height: 50rpx;
background: rgba(0, 0, 0, 0.4);
border-radius: 25rpx;
justify-content: center;
}
}
.right {
right: 0;
}
.u-home-arrow-left {
justify-content: space-between;
border-radius: 100px;
padding: 3px 7px;
opacity: 0.8;
border: 0.5px solid #dadbde;
}
}
</style>