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
| <template>
| <view
| class="cl-topbar"
| :class="{
| 'is-border': border,
| 'is-fixed': fixed,
| 'is-ios': isIos,
| 'with-mp': withMp,
| }"
| :style="{
| backgroundColor,
| color,
| zIndex,
| paddingTop,
| }"
| >
| <view
| class="cl-topbar__content"
| :style="{
| color,
| }"
| >
| <slot>
| <view class="cl-topbar__text" @tap="tapTitle">
| <text class="cl-topbar__title" v-if="title">{{ title }}</text>
| <text class="cl-topbar__description" v-if="description">{{ description }}</text>
| </view>
| </slot>
| </view>
|
| <view class="cl-topbar__prepend">
| <view class="cl-topbar__icon" v-if="showBack" @tap="back">
| <text class="cl-icon-home" v-if="isFirst"></text>
| <text class="cl-icon-arrow-left" v-else></text>
| </view>
|
| <slot name="prepend"></slot>
| </view>
|
| <view class="cl-topbar__append">
| <slot name="append"></slot>
| </view>
| </view>
| </template>
|
| <script lang="ts">
| import { computed, defineComponent, onMounted, ref } from "vue";
| import { router } from "/@/cool";
| import { isIos } from "/@/cool/utils";
|
| const { statusBarHeight } = uni.getSystemInfoSync();
|
| export default defineComponent({
| name: "cl-topbar",
|
| props: {
| // 标题
| title: String,
| // 描述
| description: String,
| // 是否显示下边框
| border: {
| type: Boolean,
| default: true,
| },
| // 是否固定
| fixed: Boolean,
| // 是否兼容小程序
| withMp: Boolean,
| // 是否显示返回按钮
| showBack: {
| type: Boolean,
| default: true,
| },
| // 背景色
| backgroundColor: {
| type: String,
| default: "#fff",
| },
| // 字体颜色
| color: {
| type: String,
| default: "#000",
| },
| // 返回页面路径
| backPath: String,
| // 层级
| zIndex: {
| type: Number,
| default: 99,
| },
| },
|
| setup(props, { emit }) {
| // 是否页面栈的第一个
| const isFirst = ref(false);
|
| // 顶部内边距
| const paddingTop = computed(() => {
| return props.fixed ? `${statusBarHeight}px` : 0;
| });
|
| // 返回
| function back() {
| if (isFirst.value) {
| // H5页面刷新或者分享页时,页面栈长度只有1。此时逐个验证返回的页面路径
| if (props.backPath) {
| router.push({
| path: props.backPath,
| mode: "reLaunch",
| });
| } else {
| router.home();
| }
| } else {
| router.back();
| }
| }
|
| // 点击标题
| function tapTitle(e: any) {
| emit("title", e);
| }
|
| onMounted(() => {
| const pages = getCurrentPages();
| isFirst.value = pages.length == 1;
| });
|
| return {
| isFirst,
| paddingTop,
| back,
| tapTitle,
| isIos,
| };
| },
| });
| </script>
|
|