1. 通过 HBuilder X 下载 ColorUI,一款适应于H5、微信小程序、安卓、ios、支付宝的高颜值,高度自定义的Css组件库。页面部分方法来自ColorUI,例如侧边字母滑动。

  2. 正确路径引入vue-py.js 文件
    百度网盘链接:vue-py
    提取码:x8z6

  3. 实现代码,样式可根据需求自行调整

<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>

实现效果
在这里插入图片描述
在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐