左右联动抽屉菜单需 uni-drawer、scroll-view 双向滚动控制与 dom 位置同步协同实现;scroll-view 必设显式高度,禁用 overflow: hidden,长列表用 uni-recycle-list;右侧滚动高亮依赖节流 + 预查 offsettop + 容错判断,动态高度需延迟重算或用 getboundingclientrect。

左右联动抽屉菜单不是单一组件能解决的组合问题,本质是「uni-drawer + scroll-view 双向滚动控制 + DOM 位置同步」三者协同。直接套用 uni-drawer 或只监听 @scroll 都会失败——前者不处理联动逻辑,后者不防抖、不校验渲染就查 offsetTop,必卡顿或错位。
抽屉打开后右侧内容无法滚动或滚动卡顿
这不是 uni-drawer 的 bug,而是内部 scroll-view 没满足基础渲染条件:
-
scroll-view必须设显式高度(如style="height: calc(100vh - 120rpx);"),不能依赖flex: 1或100vh(iOS 小程序中vh不可靠) - 父容器不能有
overflow: hidden,否则 iOS 真机下 touch 事件被截断 - 内容超 50 条时禁用
v-for直接渲染,改用uni-recycle-list,否则内存暴涨、滑动掉帧 - H5 和微信小程序建议加
enhanced="true"提升滚动流畅度;nvue 页面下只认px单位,需条件编译
左侧点击菜单,右侧不滚到对应区块
常见错误是只写 scroll-into-view 却没确保目标 id 已存在、且右侧 scroll-view 已完成渲染:
- 每个右侧分类区块必须带唯一
id(如id="category-0"),且不能以数字开头(微信小程序会报错) - 点击事件里不能直接赋值
this.rightScrollInto = 'category-' + index,要先this.$nextTick(() => { ... })等 DOM 更新 - 如果右侧数据异步加载(如从接口拉取),需在
then回调里再触发滚动,或监听watch数据长度变化 - 别在
onPageScroll里操作——它只响应页面级滚动,对scroll-view无效
右侧滚动时左侧菜单高亮错位或不更新
核心是滚动节流 + offsetTop 缓存 + 容错判断,不是每帧都查 DOM:
- 在
onReady中用uni.createSelectorQuery()预查所有分类区块的offsetTop,存进this.categoryOffsets = [],避免滚动中重复查询 - 监听右侧
scroll-view的@scroll,但用throttle(50)节流(可手写简单节流函数,不用引入 lodash) - 遍历时用
scrollTop + 100 >= offset && scrollTop 判断“当前最顶部未滚出视口”的项(+100 是容错偏移,防临界点误判) - 找到匹配索引后,更新
this.leftActiveIndex,再通过scroll-into-view让左侧菜单自动定位到可视区
最易被忽略的是:右侧区块高度动态(比如图片懒加载导致高度变化),会导致缓存的 offsetTop 失效。此时要么等图片加载完再查一次,要么改用 getBoundingClientRect().top 实时算——但必须限定只在滚动停止后触发,否则性能崩盘。











