uniapp-实现左侧菜单栏与右侧功能区联动~(保姆级)个人思路,需求实测实现啦~

1、需求1:实现左侧菜单栏与右侧功能区联动~。当点击切换左侧菜单栏时需变色同时需将其对应右侧功能区节点滑动至顶部。

2、需求2:实现滑动右侧功能区,当其所处的功能区节点刚刚触顶时,需切换左侧菜单栏与之对应。

3、效果如下:

4、代码实现

需求1:

html

<!-- 侧边栏 -->
<view class="aside-main">
	<scroll-view scroll-y class="scroll-Y1" :style="'height:'+ mainH" scroll-with-animation>
		<view :class="num==index?'active':''" 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 :src="i.url" class="min-img"></image>
			    <text>{{item.title}}</text>
		    </view>
	    </view>
    </scroll-view>
</view>

css

js

// 侧边栏切换
asid(index) {
// 变色
	this.num = index
	// 通过uniapp的scroll-into-view实现与右侧功能区节点的切换联动
	this.rightview = 'rightIndex' + index
},

需求2:

js

5、需求实测实现啦~

炒毛豆也是刚刚接触小程序。3年后台经验。后续会将学习心得不定时记录~(仅做个人笔记使用)

完整代码:

<template>
	<view>
		<!-- 适配小程序 -->
		<!-- #ifdef MP -->
		<!-- 头部搜索栏 -->
		<!-- 使用组件,可参考uniapp的esaycomezi组件 -->
		<search>
			<!-- 具名插槽 -->
			<view slot="left">
				<img src="@/static/images/扫码.png" class="icon" @click="re()" />
			</view>

			<div class="serch" slot="center">
				<img src="@/static/images/搜索.png" class="icon1" />
				<input type="search" placeholder="搜索..." placeholder-style="place" @click="searchTo()" />
			</div>
			<button class="btn" slot="right">搜索</button>
		</search>
		<!-- #endif -->

		<!-- 内容区 -->
		<!-- 侧边栏 -->
		<view class="aside-main">
			<scroll-view scroll-y class="scroll-Y1" :style="'height:'+ mainH" scroll-with-animation>
				<view :class="num==index?'active':''" 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 :src="i.url" class="min-img"></image>
						<text>{{item.title}}</text>
					</view>
				</view>
			</scroll-view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				mainH: 400,
				num: 0,
				leftview: '',
				rightview: '',
				// 所有的节点坐标
				nodes: [],
				asideList: [{
						title: "手机",
						list: [{
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}]
					},
					{
						title: "电脑",
						list: [{
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}]
					},
					{
						title: "华为",
						list: [{
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}]
					},
					{
						title: "小米",
						list: [{
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}]
					},
					{
						title: "苹果",
						list: [{
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}, {
							url: "../../static/images/sex5.jpg"
						}]
					},
					{
						title: "vivo",
						list: [{
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}, {
							url: "../../static/images/sex2.jpg"
						}]
					}
				]
			}
		},
		created() {
			// 调用uniapp的api获取系统信息,如浏览器可视区高度
			// 实现向下滑动,只有内容区可以滑动
			uni.getSystemInfo({
				success: (res) => {
					// 将upx转换成px
					// 可视区高度减去导航栏高度
					this.mainH = res.windowHeight - uni.upx2px(88) + 'px';
				}
			})
			// 得到页面加载完成时所有的.min节点的坐标位置,主要为top值
			this.coordinate()
		},
		methods: {
			// 扫码
			re() {
				uni.scanCode({
					success: function(res) {
						console.log('条码类型:' + res.scanType);
						console.log('条码内容:' + res.result);
					}
				});
			},
			// 搜索
			searchTo() {
				// 跳转路由,跳转到搜索页面
				uni.navigateTo({
					url: "../searchmain/searchmain"
				})
			},
			// 侧边栏切换
			asid(index) {
				// 变色
				this.num = index
				// 通过uniapp的scroll-into-view实现与右侧功能区节点的切换联动
				this.rightview = 'rightIndex' + index
			},
			// 滑动触顶事件
			scrolltop() {
				this.num = 0
			},
			// 滑动触底事件
			scrollbuttom() {
				this.num = this.nodes.length - 1
			},
			// 滑动右边内容区实现与左侧菜单栏联动效果
			// 监听滑动事件
			scrollright(e) {
				// 每一次滑动之前都做一遍跟随,用来解决侧边栏切换不联动问题(重要!!!不加是有bug的)
				this.asid()
				// 拿到滑动的距离(记住初始滑动距离是0!!很重要)
				console.log('滑动的距离', e.detail.scrollTop)
				// 遍历存储所有节点top坐标的数组nodes(默认从下标1开始,因为初始状态的左侧菜单栏与右侧功能区就是对应的!!)
				for (let i = 1; i < this.nodes.length; i++) {
					// 判断滑动的距离+初始节点的top值!!(这里就是为什么在上面特意提醒要牢记滑动距离的初始值是0的原因,这里将滑动距离加上初始节点的top值是为了将二者放在一个'水平线'上,便于后面比较)是否大于等于当前功能区节点的top值并且小于等于下一个的节点的top值,如果满足条件将切换左侧菜单栏变色的标识符num的值变为当前节点的i。同时需额外判断滑动的距离+初始节点的top值是否大于最后一个功能区节点的top值,因为如果不单独判断的话,原判断逻辑针对最后一个节点是满足不了并条件的。判断头部同理,同时需搭配触顶与触底事件。
					if (e.detail.scrollTop + this.nodes[0] >= this.nodes[i] && e.detail.scrollTop + this.nodes[0] <= this
						.nodes[i + 1]) {
						this.num = i
					} else if (e.detail.scrollTop + this.nodes[0] < this.nodes[1]) {
						this.num = 0
					} else if (e.detail.scrollTop + this.nodes[0] > this.nodes[this.nodes.length - 1]) {
						this.num = this.nodes.length - 1
					}
				}
			},
			// 获取右侧内容区每个指定节点的坐标信息(即左侧菜单栏所对应的每一个功能区的顶部坐标),该方法只在created生命周期中执行一遍即可
			coordinate() {
				const query = uni.createSelectorQuery().in(this);
				query.selectAll(".min").boundingClientRect((data) => {
					// 获取每一个功能区的全部坐标对象(数组形式)
					console.log("得到布局位置信息" + JSON.stringify(data));
					console.log("节点离页面顶部的距离为" + data.top);
					console.log(data)
					// 遍历每一个功能区的全部坐标对象(数组形式),拿到所有的top坐标
					for (let i = 0; i < data.length; i++) {
						console.log("每个节点的top坐标", data[i].top)
						// 将每个top坐标push进一个空数组nodes中
						this.nodes.push(data[i].top)
					}
					console.log("nodes", this.nodes)
				})
				.exec();
			}
		}
	}
</script>

<style>
	.active {
		color: red;
	}

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

	.minmi {
		display: flex;
		flex-direction: column;
	}

	.min-img {
		width: 150upx;
		height: 100upx;
	}

	.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;
		margin: 50upx;
	}

	.scroll-Y2 {
		flex: 3;
		box-sizing: border-box;
	}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值