-
通过 HBuilder X 下载 ColorUI,一款适应于H5、微信小程序、安卓、ios、支付宝的高颜值,高度自定义的Css组件库。页面部分方法来自ColorUI,例如侧边字母滑动。
-
正确路径引入vue-py.js 文件
百度网盘链接:vue-py
提取码:x8z6 -
实现代码,样式可根据需求自行调整
<template>
<view class="group-members-page-top box-size14">
<uni-search-bar class="mt12" :radius='24' bgColor="#f9f9f9" placeholder="搜索"></uni-search-bar>
<ren-dropdown-filter class="mt16" :filterData='groupMembersFilterData'></ren-dropdown-filter>
</view>
<view class="group-members-scroll">
<scroll-view scroll-y class="indexes" :scroll-into-view="'indexes-'+ listCurID" :style="[{height:'calc(100vh - '+ CustomBar + 'px)'}]" :scroll-with-animation="true" :enable-back-to-top="true">
<block v-for="(item,index) in list" :key="index">
<view :class="'indexItem-' + item" :id="'indexes-' + item " :data-index="item">
<view class="letter-box box-size14" v-show="item">
<view class="action">
<text class="cuIcon-title text-orange fw500 font-color666">{{item}}</text>
</view>
</view>
<view class="cu-list menu box-size14 bgcolorfff">
<view class="cu-item card-height54 " v-for="(name,i) in names" :key="i" v-if="names[index][i]">
<view class="flex-layout height-cover middle-layout">
<image class="head_portrait border-radius8" :src="head_portrait"></image>
<view class="ml16">
<text class="name-color">{{names[index][i]}}</text>
<p class="font-size12 font-color999">某某某科技有限公司</p>
</view>
</view>
</view>
</view>
</view>
</block>
</scroll-view>
<view class="indexBar" :style="[{height:'calc(100vh - ' + CustomBar + 'px)'}]">
<view class="indexBar-box font-size12 font-color999" @touchstart="tStart" @touchend="tEnd" @touchmove.stop="tMove">
<view class="indexBar-item" v-for="(item,index) in list" :key="index" :id="index" @touchstart="getCur" @touchend="setCur">{{item}}</view>
</view>
</view>
<!--选择显示-->
<view v-show="!hidden" class="indexToast">
{{listCur}}
</view>
</view>
</template>
<script>
import vPinyin from '@/common/vue-py.js';
export default {
data() {
return {
StatusBar: this.StatusBar,
CustomBar: this.CustomBar,
hidden: true,
listCurID: '',
listCur: '',
FristPin: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'W', 'X', 'Y', 'Z'],
items: {},
list: [],
names:[]
}
},
onLoad() {
// 请求接口返回的数据
let res = {
data: [{
name: '夏侯子惠'
},{
name: '双锦'
},{
name: '奚听云'
},{
name: '寿信鸥'
},{
name: '瑞雨筠'
},{
name: '奉琴轩'
},{
name: '荀悠奕'
},{
name: '仁怜珊'
},{
name: '望山雁'
},{
name: '柳思宸'
},{
name: '常晨星'
},{
name: '逮访彤'
},{
name: '贝蕴'
},{
name: '睢沈思'
},{
name: '绳沛凝'
},{
name: '师从丹'
},{
name: '隋语柔'
},{
name: '楼璧'
},{
name: '昝诗晗'
},{
name: '邛幼白'
},{
name: '申和颂'
},{
name: '宁锦'
},{
name: '范思云'
},{
name: '完成和'
}]
}
var itemArr = [];
for (let i = 0; i < res.data.length; i++) {
//遍历数组,拿到文字名称
let itemName = res.data[i].name;
//取全部文字的首字母
let fristName = vPinyin.chineseToPinYin(res.data[i].name); //这里截取首字母的第一位
//给原json添加首字母键值对
res.data[i].first = fristName;
//放入新数组
itemArr.push(res.data[i]);
}
let items = {};
//根据首字母键值对给原数据按首字母分类
for (let i = 0; i < this.FristPin.length; i++) {//这里的FirstPin是一个写入了所有字母的数组,见data中
var thisFristPin = this.FristPin[i];
items[this.FristPin[i]] = itemArr.filter(function(value) {
return value.first === thisFristPin;
});
}
let thisFirst = '';
var nameArr = [];
for (let i = 0; i < 22; i++) {//22个字母
let thisLength = items[this.FristPin[i]].length;//当前首字母有几个同字母的字段
if(thisLength > 0){//大于0,排除空数组
for(let j = 0 ;j < thisLength;j++){
let newFirst = items[this.FristPin[i]][j].first;//获取当前字母
if(thisFirst == newFirst){//判断当前字母和获取字母是否相同
nameArr.push(items[this.FristPin[i]][j].name);
continue;
}else{
thisFirst = newFirst;
nameArr = [];
nameArr.push(items[this.FristPin[i]][j].name)
}
this.list.push(newFirst);//输出结果
this.names.push(nameArr);
}
}
}
console.log(this.list, this.names, '789')
},
onReady() {
let that = this;
uni.createSelectorQuery().select('.indexBar-box').boundingClientRect(function(res) {
that.boxTop = res.top
}).exec();
uni.createSelectorQuery().select('.indexes').boundingClientRect(function(res) {
that.barTop = res.top
}).exec()
},
methods: {
//获取文字信息
getCur(e) {
this.hidden = false;
this.listCur = this.list[e.target.id];
},
setCur(e) {
this.hidden = true;
this.listCur = this.listCur
},
//滑动选择Item
tMove(e) {
let y = e.touches[0].clientY,
offsettop = this.boxTop,
that = this;
//判断选择区域,只有在选择区才会生效
var thatCur = this.listCur;
if (y > offsettop) {
let num = parseInt((y - offsettop) / 20);
this.listCur = that.list[num]
}if(this.listCur == undefined){//当滑动为空时获取最后的字母显示
this.listCur = thatCur
};
console.log(this.listCur)
},
//触发全部开始选择
tStart() {
this.hidden = false
},
//触发结束选择
tEnd() {
this.hidden = true;
this.listCurID = this.listCur
},
indexSelect(e) {
let that = this;
let barHeight = this.barHeight;
let list = this.list;
let scrollY = Math.ceil(list.length * e.detail.y / barHeight);
for (let i = 0; i < list.length; i++) {
if (scrollY < i + 1) {
that.listCur = list[i];
that.movableY = i * 20
return false
}
}
}
}
}
</script>
<style>
.group-members-page-top {
height: 168upx;
background: #fff;
padding-top: 1px;
}
page{height: 100%;}
.indexes {
position: relative;
}
.indexBar {
position: fixed;
right: 0px;
top: 50%;
padding: 20upx 20upx 20upx 60upx;
display: flex;
align-items: center;
transform: translateY(-50%);
}
.indexBar .indexBar-box {
width: 40upx;
height: auto;
/* background: #fff; */
display: flex;
flex-direction: column;
/* box-shadow: 0 0 20upx rgba(0, 0, 0, 0.1); */
border-radius: 10upx;
}
.indexBar-item {
flex: 1;
width: 40upx;
height: 40upx;
display: flex;
align-items: center;
justify-content: center;
font-size: 24upx;
color: #888;
}
movable-view.indexBar-item {
width: 40upx;
height: 40upx;
z-index: 9;
position: relative;
}
movable-view.indexBar-item::before {
content: "";
display: block;
position: absolute;
left: 0;
top: 10upx;
height: 20upx;
width: 4upx;
background-color: #f37b1d;
}
.indexToast {
position: fixed;
top: 0;
right: 80upx;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
width: 100upx;
height: 100upx;
border-radius: 10upx;
margin: auto;
color: #fff;
line-height: 100upx;
text-align: center;
font-size: 48upx;
}
.letter-box {
height: 52upx;
line-height: 52upx;
}
.head_portrait {
width: 72upx;
height: 72upx;
}
.name-color{
color: #0d0e15;
}
.group-members-scroll {
flex:1;
overflow-y: scroll;
}
</style>
实现效果