当前位置: 首页 > news >正文

UniApp 商品分类左右联动技术文档

一、功能说明

实现 商品分类左右联动 效果:

  • 点击左侧分类 → 右侧自动滚动到对应分类内容;

  • 滚动右侧内容 → 左侧自动高亮当前分类。

二、核心结构

<scroll-view class="menuLeft" scroll-y><view v-for="(item,index) in menuList" @click="changeCurrent(index)" :class="{currentMenu: currentIndex==index}">{{item.name}}</view>
</scroll-view><scroll-view class="menuRight" scroll-y :scroll-top="scrollTop" @scroll="scrollRight"><view class="menuDetailBox" v-for="(item,index) in menuList" :key="index"><view class="title">{{item.name}}</view><view v-for="menu in item.children" class="menu">{{menu.name}}</view></view>
</scroll-view>

三、主要逻辑

1️⃣ 初始化高度计算(onLoad)

获取右侧每个分类区块高度,并计算累计值:

query.selectAll('.menuDetailBox').boundingClientRect(data => {this.newData = data.map((item, i) => {item.offsetHeight = data.slice(0, i + 1).reduce((sum, cur) => sum + cur.height, 0)return item})
}).exec()

2️⃣ 点击左侧分类

根据预计算的高度滚动右侧内容:

changeCurrent(index) {this.currentIndex = indexthis.scrollTop = this.newData[index - 1]?.offsetHeight || 0
}

3️⃣ 右侧滚动时联动左侧

监听滚动距离,动态更新左侧高亮:

scrollRight(e) {const top = e.detail.scrollTopfor (let i = 0; i < this.newData.length; i++) {if (top < this.newData[i].offsetHeight) {this.currentIndex = ibreak}}
}

四、样式要点

  • 左侧固定宽度 200rpx,右侧自适应。

  • 当前分类高亮(加粗 / 红条标识)。

  • 右侧滚动视图需开启 scroll-y="true"

.currentMenu { font-weight: 700; }
.line::before { background-color: red; }

五、总结

  • 使用 scrollTop + 高度累计实现左右同步滚动。

  • 左右两栏通过 currentIndex 实现联动高亮。

  • 简单可靠,适用于电商、分类导航场景。

完整代码

<template><view class="menuBox"><view class="menuContent"><scroll-view scroll-y="true" class="menuLeft"><view class="menuType" @click="changeCurrent(index)" v-for="(item,index) in menuList":class="{currentMenu:currentIndex==index}">{{item.name}}</view><view class="line" :style="{top:currentIndex*90 +'rpx'}"></view></scroll-view><scroll-view :scroll-top="scrollTop" @scroll="scrollRight" class="menuRight" scroll-y="true"><div class="menuDetailBox" v-for="(item,index) in menuList" :key="index"><div class="title">{{item.name}}</div><div class="menu" v-for="(menu,index) in item.children" :key="index"><div class="d2">123</div><div class="menuName">{{menu.name}}</div></div></div></scroll-view></view></view>
</template><script>export default {data() {return {newData:[],  // 拿到右侧所有的商品列表元素scrollTop: 0,currentIndex: 0,menuList: [{"id": 1,"name": "手机数码","children": [{"id": 101,"name": "手机"},{"id": 105,"name": "数码相机"}]},{"id": 2,"name": "家用电器","children": [{"id": 201,"name": "电视机"},{"id": 204,"name": "冰箱"},{"id": 205,"name": "吸尘器"}]},{"id": 3,"name": "服饰鞋包","children": [{"id": 301,"name": "男装"},{"id": 302,"name": "女装"},{"id": 303,"name": "运动鞋"},{"id": 304,"name": "箱包"},{"id": 305,"name": "配饰"}]},{"id": 4,"name": "美妆个护","children": [{"id": 401,"name": "面部护肤"},{"id": 402,"name": "彩妆"},{"id": 403,"name": "洗发护发"},{"id": 404,"name": "身体护理"},{"id": 405,"name": "香水"}]},{"id": 5,"name": "母婴玩具","children": [{"id": 501,"name": "奶粉"},{"id": 502,"name": "尿不湿"},{"id": 503,"name": "婴儿用品"},{"id": 504,"name": "儿童玩具"},{"id": 505,"name": "孕妇用品"}]},{"id": 6,"name": "食品饮料","children": [{"id": 601,"name": "休闲零食"},{"id": 602,"name": "粮油调味"},{"id": 603,"name": "饮料酒水"},{"id": 604,"name": "冲调速食"},{"id": 605,"name": "生鲜水果"}]},{"id": 7,"name": "家居家装","children": [{"id": 701,"name": "家具"},{"id": 702,"name": "灯具"},{"id": 703,"name": "床上用品"},{"id": 704,"name": "厨房用品"},{"id": 705,"name": "装饰摆件"}]},{"id": 8,"name": "运动户外","children": [{"id": 801,"name": "跑步装备"},{"id": 802,"name": "健身器材"},{"id": 803,"name": "户外鞋服"},{"id": 804,"name": "骑行装备"},{"id": 805,"name": "垂钓用品"}]},{"id": 9,"name": "汽车用品","children": [{"id": 901,"name": "机油"},{"id": 902,"name": "轮胎"},{"id": 903,"name": "车载电器"},{"id": 904,"name": "清洁用品"},{"id": 905,"name": "维修配件"}]},{"id": 10,"name": "图书文娱","children": [{"id": 1001,"name": "文学小说"},{"id": 1002,"name": "少儿读物"},{"id": 1003,"name": "教育考试"},{"id": 1004,"name": "艺术设计"},{"id": 1005,"name": "音像制品"}]}]}},methods: {changeCurrent(index) {this.currentIndex = indexthis.scrollTop = this.newData[index-1]?.offsetHeight || 0},scrollRight(e) {// console.log(e.detail.scrollTop,'scrollRight');const query = uni.createSelectorQuery().in(this);for (let i = 0; i < this.newData.length; i++) {let el = this.newData[i]if (e.detail.scrollTop < el.offsetHeight) {this.currentIndex = ireturn true}}}},onLoad() {uni.setNavigationBarTitle({title: '你好'})const query = uni.createSelectorQuery().in(this);query.selectAll('.menuDetailBox').boundingClientRect(data => {console.log('所有分类项:', data);this.newData = data.map((item, index) => {function fgfg(total) {let sum = 0for (var i = 0; i <= total; i++) {sum += data[i].height}return sum}item.offsetHeight = fgfg(index)return item})}).exec();}}
</script><style lang="scss" scoped>.menuBox {height: calc(100vh);display: flex;flex-direction: column;border: 1px solid #ccc;margin: 0 10rpx;.menuContent {height: calc(100vh);overflow: auto;position: relative;display: flex;position: sticky;top: 0rpx;.menuLeft {float: left;position: relative;width: 200rpx;background-color: #f5f5f5;.menuType {transition: all 0.4s;position: relative;z-index: 999999999;height: 90rpx;display: flex;align-items: center;padding-left: 20rpx;&.currentMenu {font-weight: 700;}}}.menuRight {flex: 1;background-color: #fff;.menuDetailBox {.title {height: 60rpx;display: flex;align-items: center;}.menu {background-color: skyblue;height: 100rpx;display: flex;justify-content: center;&:not(:nth-last-of-type(1)) {margin-bottom: 20rpx;}.d2 {width: 60rpx;height: 60rpx;}.menuName {flex: 1;margin-left: 20rpx;}}}}}}.line {position: absolute;left: 0;top: 0;height: 90rpx;width: 100%;background-color: #fff;z-index: 999;transition: all 0.4s;&::before {content: '';position: absolute;left: 0;top: 0;height: 90rpx;width: 4rpx;background-color: red;z-index: 999;transition: all 0.4s}}
</style>

http://www.dtcms.com/a/605106.html

相关文章:

  • pytest 入门指南:Python 测试框架从零到一(2025 实战版)
  • SpringBoot教程(三十三)| SpringBoot集成MinIO
  • 【开题答辩全过程】以 基于.NET MVC的线上鞋服交易系统设计与实现为例,包含答辩的问题和答案
  • MySQL 全体系深度解析(存储引擎、事务、日志、MVCC、锁、索引、执行计划、复制、调优)
  • SpringMVC基础教程(1)--MVC/DispathcerServlet
  • 在streampark运行paimon-flink-action-1.20.0.jar
  • AI得贤面试智能体:重构企业招聘新范式
  • 硅基计划6.0 陆 JavaEE HttpHttps协议
  • 稳定边界层高度参数化方案的回归建模
  • 企业网站推广方法wap网站预览
  • 可以做推广的门户网站wordpress适合中国的小插件介绍
  • Dubbo服务治理全解析:从零搭建高可用微服务架构
  • java List怎么转换为Vector
  • 2023年辽宁省数学建模竞赛-B题 数据驱动的水下导航适配区分类预测-基于支持向量机对水下导航适配区分类的研究
  • 机器学习--KNN算法中的距离、范数、正则化
  • openGauss向量数据库功能实操测评:轻量部署下的高维检索能力
  • php做网站还是linuxseo服务外包费用
  • 《算法通关指南:算法基础篇 ---- 二维前缀和 — 1. 【模板】二维度前缀和,2.激光炸弹》
  • SpringBoot+openGauss DataVec构建高效RAG知识库实践
  • JVM 垃圾回收算法的详细介绍
  • 生成式引擎优化(GEO)实用指南(三):结构化内容与AI优化策略
  • 114啦怎么建设网站怎么样推广自己的公司
  • 可视化图标开发“懂一点”|数据可视化术语表
  • SpringMVC(1)学习
  • 高频Linux 面试题
  • 芜湖效能建设网站重庆发布公众号
  • Spring Boot 多环境配置详解:Maven Profile vs 启动参数注入
  • 《Chart.js 饼图:高效与灵活的数据可视化工具详解》
  • 力扣每日刷题251113
  • erp网站开发网站后台管理系统源码下载