近期有项目要求做一个类似美团的左右列联动的商品选择列表,但是去插件市场找了一圈基本都是整个页面的列表,没有在某个区域内实现左右列联动的,于是自己写了一套

先看成品

原理:左右列滑动用scroll-view标签实现

<view class="popupBoxType2">
							<view class="left">
								<scroll-view scroll-y style="height: 50vh;" :scroll-into-view="currentTitleId" scroll-with-animation>
									<view v-for="(item,index) in tagEveryList" :key="index" @tap="scrollTo(item.id)"  :id="'tagTitle'+item.id"
										class="classIdsListTitle" :class="{classIdsListTitleActive:item.id==currentActive}">
										<!-- 左侧选项内容 -->
										{{item.name}}
									</view>
								</scroll-view>
							</view>
							<!-- 右侧滚动区域 -->
							<view class="right">
								<scroll-view scroll-y :scroll-into-view="currentId" style="height: 50vh;" scroll-with-animation
									@scroll="rightScroll">
									<!-- 右侧内容区域 -->
									<view class="rightItem" v-for="(item,index) in tagEveryList" :key="index"
										:id='"tag"+item.id'>
										<span class="nameBox">
										<image :src="item.iconUrl" style="width: 22px;height: 22px;margin-right: 5px;"></image>
										{{item.name}}</span>
										<view class="rightItemDesc">
											<span v-for="(item1,index1) in item.children" :key="index1"
												:class="{tagActive:tagsKeys.includes(item1.id),
												tagActive:item1.id===tagsKey1&&index===0,
												tagActive:item1.id===tagsKey2&&index===1,
												}"
												class="rightItemDescItem" @click="tagsKeysUpda(item1,index)">{{item1.name}}</span>
										</view>
									</view>
								</scroll-view>
							</view>
						</view>
.popupBoxType2 {
				display: flex;
				height: 50vh;
				width: 100vw;
				margin-left: -15px;
				.left {
					width: 30%;
					text-align: center;
					flex-shrink: 0;

					.classIdsListTitle {
						height: 48px;
						font-weight: 400;
						font-size: 14px;
						display: flex;
						align-items: center;
						justify-content: center;
					}

					.classIdsListTitleActive {
						color: #FF6225;
						background: #FFEFE9;
					}
				}

				.right {
					padding: 0 15px;
					box-sizing: border-box;

					.rightItem {
						border-bottom: 1px solid #F5F5F5;
						margin: 5px 0;
						.nameBox {
							padding: 13px 0;
							font-size: 14px;
							// display: inline-block;
							display: flex;
							align-items: center;
						}

						.rightItemDesc {
							display: flex;
							flex-wrap: wrap;

							.rightItemDescItem {
								display: inline-block;
								padding: 6px 20px;
								margin-right: 20px;
								font-weight: 400;
								font-size: 14px;
								line-height: 18px;
								color: #999999;
								background: #F5F5F5;
								border-radius: 77px;
								margin-bottom: 15px;
							}
						}
					}
				}
			}

在此列表渲染时获取右侧列表每一项距离顶部的距离并整理成数组

// 获取高度列表
			getTagTopHight() {
				for(var i=0;i<this.tagEveryList.length;i++){
					uni.createSelectorQuery().select('#tag'+this.tagEveryList[i].id).boundingClientRect(res => {
						this.topHight.push(res.top-180)
					}).exec()
				}
			},

当右侧列表滑动时获取当前滑动到哪一分类下并给左侧分类赋予动态id

// 右侧滑动
			rightScroll(e) {
				if(!this.goTop){
					let top=e.detail.scrollTop
					for(let i=0;i<this.topHight.length;i++){
						if(top<50){
							this.currentActive=this.tagEveryList[0].id
							this.currentTitleId='tagTitle'+this.currentActive
							return
						}
						if(top>this.topHight[i]){
							this.currentActive=this.tagEveryList[i].id
							this.currentTitleId='tagTitle'+this.currentActive
						}
					}
				}else{
					this.goTop=false
				}
			},

到此为止,左侧跟随右侧滑动的变化而变化已经完成

下面开始右侧跟随左侧

// 点击左侧选项触发的事件
			scrollTo(id) {
				// 更新当前选中项的标识符
				this.goTop=true
				this.currentId = "tag" + id
				this.currentActive = id
			},

很简单,动态赋值,利用scroll-into-view属性,当绑定的值改变时,他会自动滚动到元素id为绑定值的地方

整理一下,核心属性就是scroll-into-view,利用动态赋值让两个scroll-view自动滚动,其次就是获取右侧列表每一项距离顶部的距离,动态计算出当前右侧滚动到哪个分类下后再将左侧动态赋值

Logo

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

更多推荐