c7add6cf
“wangming”
初始版本开发完毕
|
1
|
<template>
|
25852764
unknown
s
|
2
3
4
|
<!-- 支付宝小程序使用$u.getRect()获取组件的根元素尺寸,所以在外面套一个"壳" -->
<view>
<view class="u-index-bar">
|
c7add6cf
“wangming”
初始版本开发完毕
|
5
|
<slot />
|
25852764
unknown
s
|
6
7
8
9
10
11
|
<view v-if="showSidebar" class="u-index-bar__sidebar" @touchstart.stop.prevent="onTouchMove" @touchmove.stop.prevent="onTouchMove"
@touchend.stop.prevent="onTouchStop" @touchcancel.stop.prevent="onTouchStop">
<view v-for="(item, index) in indexList" :key="index" class="u-index-bar__index" :style="{zIndex: zIndex + 1, color: activeAnchorIndex === index ? activeColor : ''}"
:data-index="index">
{{ item }}
</view>
|
c7add6cf
“wangming”
初始版本开发完毕
|
12
|
</view>
|
25852764
unknown
s
|
13
14
15
16
|
<view class="u-indexed-list-alert" v-if="touchmove && indexList[touchmoveIndex]" :style="{
zIndex: alertZIndex
}">
<text>{{indexList[touchmoveIndex]}}</text>
|
c7add6cf
“wangming”
初始版本开发完毕
|
17
18
|
</view>
</view>
|
c7add6cf
“wangming”
初始版本开发完毕
|
19
20
21
22
|
</view>
</template>
<script>
|
25852764
unknown
s
|
23
24
25
26
|
var indexList = function() {
var indexList = [];
var charCodeOfA = 'A'.charCodeAt(0);
for (var i = 0; i < 26; i++) {
|
c7add6cf
“wangming”
初始版本开发完毕
|
27
28
29
|
indexList.push(String.fromCharCode(charCodeOfA + i));
}
return indexList;
|
25852764
unknown
s
|
30
31
|
};
|
c7add6cf
“wangming”
初始版本开发完毕
|
32
|
/**
|
25852764
unknown
s
|
33
34
35
36
37
38
39
40
41
42
43
44
|
* indexList 索引列表
* @description 通过折叠面板收纳内容区域,搭配<u-index-anchor>使用
* @tutorial https://www.uviewui.com/components/indexList.html#indexanchor-props
* @property {Number String} scroll-top 当前滚动高度,自定义组件无法获得滚动条事件,所以依赖接入方传入
* @property {Array} index-list 索引字符列表,数组(默认A-Z)
* @property {Number String} z-index 锚点吸顶时的层级(默认965)
* @property {Boolean} sticky 是否开启锚点自动吸顶(默认true)
* @property {Number String} offset-top 锚点自动吸顶时与顶部的距离(默认0)
* @property {String} highlight-color 锚点和右边索引字符高亮颜色(默认#2979ff)
* @event {Function} select 选中右边索引字符时触发
* @example <u-index-list :scrollTop="scrollTop"></u-index-list>
*/
|
c7add6cf
“wangming”
初始版本开发完毕
|
45
|
export default {
|
25852764
unknown
s
|
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
|
name: "u-index-list",
props: {
sticky: {
type: Boolean,
default: true
},
zIndex: {
type: [Number, String],
default: ''
},
scrollTop: {
type: [Number, String],
default: 0,
},
offsetTop: {
type: [Number, String],
default: 0
},
indexList: {
type: Array,
default () {
return indexList()
}
},
activeColor: {
type: String,
default: '#2979ff'
}
},
created() {
// #ifdef H5
this.stickyOffsetTop = this.offsetTop ? uni.upx2px(this.offsetTop) : 44;
// #endif
// #ifndef H5
this.stickyOffsetTop = this.offsetTop ? uni.upx2px(this.offsetTop) : 0;
// #endif
// 只能在created生命周期定义children,如果在data定义,会因为循环引用而报错
this.children = [];
|
c7add6cf
“wangming”
初始版本开发完毕
|
84
|
},
|
c7add6cf
“wangming”
初始版本开发完毕
|
85
86
|
data() {
return {
|
25852764
unknown
s
|
87
88
89
90
91
|
activeAnchorIndex: 0,
showSidebar: true,
// children: [],
touchmove: false,
touchmoveIndex: 0,
|
c7add6cf
“wangming”
初始版本开发完毕
|
92
93
94
|
}
},
watch: {
|
25852764
unknown
s
|
95
96
|
scrollTop() {
this.updateData()
|
c7add6cf
“wangming”
初始版本开发完毕
|
97
98
|
}
},
|
25852764
unknown
s
|
99
100
101
102
103
|
computed: {
// 弹出toast的z-index值
alertZIndex() {
return this.$u.zIndex.toast;
}
|
c7add6cf
“wangming”
初始版本开发完毕
|
104
105
|
},
methods: {
|
25852764
unknown
s
|
106
107
108
109
110
111
112
113
|
updateData() {
this.timer && clearTimeout(this.timer);
this.timer = setTimeout(() => {
this.showSidebar = !!this.children.length;
this.setRect().then(() => {
this.onScroll();
});
}, 0);
|
c7add6cf
“wangming”
初始版本开发完毕
|
114
|
},
|
25852764
unknown
s
|
115
116
117
118
119
120
|
setRect() {
return Promise.all([
this.setAnchorsRect(),
this.setListRect(),
this.setSiderbarRect()
]);
|
c7add6cf
“wangming”
初始版本开发完毕
|
121
|
},
|
25852764
unknown
s
|
122
123
124
125
126
127
128
129
130
|
setAnchorsRect() {
return Promise.all(this.children.map((anchor, index) => anchor
.$uGetRect('.u-index-anchor-wrapper')
.then((rect) => {
Object.assign(anchor, {
height: rect.height,
top: rect.top
});
})));
|
c7add6cf
“wangming”
初始版本开发完毕
|
131
|
},
|
25852764
unknown
s
|
132
133
134
135
136
137
138
|
setListRect() {
return this.$uGetRect('.u-index-bar').then((rect) => {
Object.assign(this, {
height: rect.height,
top: rect.top + this.scrollTop
});
});
|
c7add6cf
“wangming”
初始版本开发完毕
|
139
|
},
|
25852764
unknown
s
|
140
141
142
143
144
145
146
|
setSiderbarRect() {
return this.$uGetRect('.u-index-bar__sidebar').then(rect => {
this.sidebar = {
height: rect.height,
top: rect.top
};
});
|
c7add6cf
“wangming”
初始版本开发完毕
|
147
|
},
|
25852764
unknown
s
|
148
149
150
151
152
153
154
155
156
157
158
159
|
getActiveAnchorIndex() {
const {
children
} = this;
const {
sticky
} = this;
for (let i = this.children.length - 1; i >= 0; i--) {
const preAnchorHeight = i > 0 ? children[i - 1].height : 0;
const reachTop = sticky ? preAnchorHeight : 0;
if (reachTop >= children[i].top) {
return i;
|
c7add6cf
“wangming”
初始版本开发完毕
|
160
|
}
|
25852764
unknown
s
|
161
162
|
}
return -1;
|
c7add6cf
“wangming”
初始版本开发完毕
|
163
|
},
|
25852764
unknown
s
|
164
|
onScroll() {
|
c7add6cf
“wangming”
初始版本开发完毕
|
165
|
const {
|
25852764
unknown
s
|
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
|
children = []
} = this;
if (!children.length) {
return;
}
const {
sticky,
stickyOffsetTop,
zIndex,
scrollTop,
activeColor
} = this;
const active = this.getActiveAnchorIndex();
this.activeAnchorIndex = active;
if (sticky) {
let isActiveAnchorSticky = false;
if (active !== -1) {
isActiveAnchorSticky =
children[active].top <= 0;
}
children.forEach((item, index) => {
if (index === active) {
let wrapperStyle = '';
let anchorStyle = {
color: `${activeColor}`
};
if (isActiveAnchorSticky) {
wrapperStyle = {
height: `${children[index].height}px`
};
anchorStyle = {
position: 'fixed',
top: `${stickyOffsetTop}px`,
zIndex: `${zIndex ? zIndex : this.$u.zIndex.indexListSticky}`,
color: `${activeColor}`
};
}
item.active = active;
item.wrapperStyle = wrapperStyle;
item.anchorStyle = anchorStyle;
} else if (index === active - 1) {
const currentAnchor = children[index];
const currentOffsetTop = currentAnchor.top;
const targetOffsetTop = index === children.length - 1 ?
this.top :
children[index + 1].top;
const parentOffsetHeight = targetOffsetTop - currentOffsetTop;
const translateY = parentOffsetHeight - currentAnchor.height;
const anchorStyle = {
position: 'relative',
transform: `translate3d(0, ${translateY}px, 0)`,
zIndex: `${zIndex ? zIndex : this.$u.zIndex.indexListSticky}`,
color: `${activeColor}`
};
item.active = active;
item.anchorStyle = anchorStyle;
} else {
item.active = false;
item.anchorStyle = '';
item.wrapperStyle = '';
}
});
|
c7add6cf
“wangming”
初始版本开发完毕
|
228
229
|
}
},
|
25852764
unknown
s
|
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
|
onTouchMove(event) {
this.touchmove = true;
const sidebarLength = this.children.length;
const touch = event.touches[0];
const itemHeight = this.sidebar.height / sidebarLength;
let clientY = 0;
clientY = touch.clientY;
let index = Math.floor((clientY - this.sidebar.top) / itemHeight);
if (index < 0) {
index = 0;
} else if (index > sidebarLength - 1) {
index = sidebarLength - 1;
}
this.touchmoveIndex = index;
this.scrollToAnchor(index);
|
c7add6cf
“wangming”
初始版本开发完毕
|
245
|
},
|
25852764
unknown
s
|
246
247
248
|
onTouchStop() {
this.touchmove = false;
this.scrollToAnchorIndex = null;
|
c7add6cf
“wangming”
初始版本开发完毕
|
249
|
},
|
25852764
unknown
s
|
250
251
252
|
scrollToAnchor(index) {
if (this.scrollToAnchorIndex === index) {
return;
|
c7add6cf
“wangming”
初始版本开发完毕
|
253
|
}
|
25852764
unknown
s
|
254
255
256
257
258
259
260
261
262
263
264
265
|
this.scrollToAnchorIndex = index;
const anchor = this.children.find((item) => item.index === this.indexList[index]);
if (anchor) {
this.$emit('select', anchor.index);
uni.pageScrollTo({
duration: 0,
scrollTop: anchor.top + this.scrollTop
});
}
}
}
};
|
c7add6cf
“wangming”
初始版本开发完毕
|
266
267
268
|
</script>
<style lang="scss" scoped>
|
25852764
unknown
s
|
269
270
271
272
273
|
@import "../../libs/css/style.components.scss";
.u-index-bar {
position: relative
}
|
c7add6cf
“wangming”
初始版本开发完毕
|
274
|
|
25852764
unknown
s
|
275
276
277
278
279
280
281
282
283
284
285
|
.u-index-bar__sidebar {
position: fixed;
top: 50%;
right: 0;
@include vue-flex;
flex-direction: column;
text-align: center;
transform: translateY(-50%);
user-select: none;
z-index: 99;
}
|
c7add6cf
“wangming”
初始版本开发完毕
|
286
|
|
25852764
unknown
s
|
287
288
289
290
291
292
|
.u-index-bar__index {
font-weight: 500;
padding: 8rpx 18rpx;
font-size: 22rpx;
line-height: 1
}
|
c7add6cf
“wangming”
初始版本开发完毕
|
293
|
|
25852764
unknown
s
|
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
|
.u-indexed-list-alert {
position: fixed;
width: 120rpx;
height: 120rpx;
right: 90rpx;
top: 50%;
margin-top: -60rpx;
border-radius: 24rpx;
font-size: 50rpx;
color: #fff;
background-color: rgba(0, 0, 0, 0.65);
@include vue-flex;
justify-content: center;
align-items: center;
padding: 0;
z-index: 9999999;
}
|
c7add6cf
“wangming”
初始版本开发完毕
|
311
|
|
25852764
unknown
s
|
312
313
|
.u-indexed-list-alert text {
line-height: 50rpx;
|
c7add6cf
“wangming”
初始版本开发完毕
|
314
315
|
}
</style>
|