Uniapp左右联动案例代码

123 阅读2分钟
<template>
	<view>
		<view class="aside-main">
			<scroll-view scroll-y class="scroll-Y1" :style="'height:'+ mainH" scroll-with-animation>
				<view :class="num==index?'active':'active2'" v-for="(item,index) in asideList" :key="index"
					@click="asid(index)">{{item.title}}
				</view>
			</scroll-view>
			<!-- 右侧滑动区 -->
			<scroll-view scroll-y class="scroll-Y2" :style="'height:'+ mainH" :scroll-into-view="rightview"
				scroll-with-animation @scroll="scrollright" @scrolltoupper="scrolltop" @scrolltolower="scrollbuttom">
				<!-- 功能区节点 -->
				<view v-for="(item,index) in asideList" :key="index" class="min" :id="'rightIndex'+index">
					<view v-for="(i,j) in item.list" :key="j" class="minmi">
						<image class="imgPic" :src="i.url" mode=""></image>
						<view class="rightContainer">
							<view class="foodName">
								{{item.title}}
							</view>
							<view class="foodPrice">
								<view class="priceflex">
									<text class="zero"></text>
									{{i.price}}
								</view>
								<view class="shopCar iconfont-themeColor-write">
									选套餐
								</view>
							</view>
						</view>
					</view>
				</view>
			</scroll-view>
		</view>
		<view class="settlement">
			<view class="itemContainer">

			</view>
		</view>
	</view>
</template>

<script setup>
	import {
		ref,
		onMounted,
		getCurrentInstance
	} from 'vue'

	const mainH = ref('400')
	const num = ref(0)
	const leftview = ref('')
	const rightview = ref('')
	const nodes = ref([])
	const shopchecked = ref('自取')
	const checkedmode = (e) => {
		shopchecked.value = e
	}
	const asideList = [{
		title: "双人套餐",
		list: new Array(50).fill({
			url: "https://gitee.com/xiaojisengren/food-speed-order-img/raw/master/defaultImg/tangshi.png",
			name: '双人套餐',
			price: 32
		})
	}, {
		title: "多人套餐",
		list: new Array(50).fill({
			url: "https://gitee.com/xiaojisengren/food-speed-order-img/raw/master/defaultImg/tangshi.png",
			name: '双人套餐',
			price: 32
		})
	}, {
		title: "粥",
		list: new Array(50).fill({
			url: "https://gitee.com/xiaojisengren/food-speed-order-img/raw/master/defaultImg/tangshi.png",
			name: '双人套餐',
			price: 32
		})
	}, {
		title: "饺子",
		list: new Array(50).fill({
			url: "https://gitee.com/xiaojisengren/food-speed-order-img/raw/master/defaultImg/tangshi.png",
			name: '双人套餐',
			price: 32
		})
	}, {
		title: "小吃",
		list: new Array(50).fill({
			url: "https://gitee.com/xiaojisengren/food-speed-order-img/raw/master/defaultImg/tangshi.png",
			name: '双人套餐',
			price: 32
		})
	}, {
		title: "汤",
		list: new Array(50).fill({
			url: "https://gitee.com/xiaojisengren/food-speed-order-img/raw/master/defaultImg/tangshi.png",
			name: '双人套餐',
			price: 32
		})
	}]

	onMounted(() => {
		uni.getSystemInfo({
			success: (res) => {
				mainH.value = res.windowHeight - uni.upx2px(88) + 'px'
			}
		})
		coordinate()
	})

	const asid = (index) => {
		num.value = index
		rightview.value = 'rightIndex' + index
	}

	const scrolltop = () => {
		num.value = 0
	}

	const scrollbuttom = () => {
		num.value = nodes.value.length - 1
	}

	const scrollright = (e) => {
		console.log( nodes.value);
		for (let i = 0; i < nodes.value.length - 1; i++) { // 从0开始循环,并且减去1以避免越界
			if (e.detail.scrollTop + nodes.value[0] >= nodes.value[i] && e.detail.scrollTop + nodes.value[0] < nodes
				.value[i + 1]) {
				num.value = i;
				break; // 找到对应的索引后,退出循环
			}
		}
		// 处理边界情况
		if (e.detail.scrollTop + nodes.value[0] <= nodes.value[0]) {
			num.value = 0;
		} else if (e.detail.scrollTop + nodes.value[0] >= nodes.value[nodes.value.length - 1]) {
			num.value = nodes.value.length - 1;
		}

		console.log(num.value);
	}


	const coordinate = () => {
		const instance = getCurrentInstance(); // 获取组件实例
		const query = uni.createSelectorQuery().in(instance)
		console.log('query',query);
		query.selectAll(".min").boundingClientRect((data) => {
			console.log('data',data);
			for (let i = 0; i < data.length; i++) {
				nodes.value.push(data[i].top)
			}
		}).exec()
	}
</script>

<style lang="scss">
	.active {
		font-size: 30upx;
		color: #F9BE3E;
	}

	.active2 {
		font-size: 30upx;
	}

	.min {
		display: flex;
		flex-direction: row;
		justify-content: space-around;
		flex-wrap: wrap;
	}

	.minmi {
		display: flex;
		width: 592upx;
		margin-left: 25upx;
		padding-top: 51upx;

		.imgPic {
			width: 208upx;
			height: 167upx;
			border-radius: 10upx;
			margin-left: 20upx;
		}

		.rightContainer {
			display: flex;
			flex-direction: column;
			height: 167upx;
			box-sizing: border-box;
			justify-content: space-between;
			align-items: flex-start;
			padding-left: 18upx;
			padding-right: 18upx;
			padding-top: 18upx;
			padding-bottom: 18upx;
			flex: 1;

			.foodName {
				font-weight: 700;
				font-size: 25upx;
			}

			.foodPrice {
				display: flex;
				justify-content: space-between;
				width: 375upx;
				color: #F9BE3E;

				.priceflex {
					display: flex;
					align-items: center;

					.zero {
						font-size: 15upx;
					}
				}

				.shopCar {
					background-color: #F9BE3E;
					border-radius: 45upx;
					width: 112upx;
					height: 45upx;
					font-size: 25upx;
					text-align: center;
					line-height: 46upx;
				}
			}
		}
	}

	.aside-main {
		width: 100%;
		display: flex;
		flex-direction: row;
		justify-content: space-between;
		box-sizing: border-box;
	}

	.scroll-Y1 {
		flex: 1;
		box-sizing: border-box;
	}

	.scroll-Y1 view {
		text-align: center;
		padding-top: 33upx;
		padding-bottom: 33upx;
	}

	.scroll-Y2 {
		flex: 3;
		box-sizing: border-box;
		padding-bottom: 170upx;
	}

	.scroll-Y2 view {
		text-align: center;
		/* margin:20upx; */
	}

	.icon {
		width: 50upx;
		height: 50upx;
		margin-top: 10upx;
	}

	.icon1 {
		width: 30upx;
		height: 30upx;
		position: absolute;
		top: 15upx;
		left: 10upx;
	}

	.btn {
		width: 140upx;
		height: 60upx;
		line-height: 60upx;
		margin: 0;
		padding: 0;
		font-size: 30upx;
	}

	.serch {
		height: 60upx;
		flex: 2;
		margin-left: 20upx;
		margin-right: 20upx;
		box-sizing: border-box;
		border: solid 1upx #ccc;
		border-radius: 10upx;
		position: relative;
	}

	.serch input {
		height: 60upx;

		margin-left: 60upx;
	}
</style>