最稳方案是左侧用 scroll-view(scroll-y="true")实现固定导航与高亮联动,右侧用 swiper(vertical="false")控制分类切换,通过 scrollintoview 和 current 同步实现京东式侧滑筛选。

uni-app 里用 swiper + scroll-view 搭建侧滑分类菜单最稳
直接说结论:京东式分类筛选在 uni-app 中不推荐用原生 popup 或第三方插件硬套,核心是「左侧分类导航固定 + 右侧内容区域可横向滚动」,靠 swiper 控制主区切换、scroll-view 实现左侧高亮联动,比手写 touchmove 更可靠、兼容性更好。
常见错误是把整个筛选栏做成一个横向 scroll-view,结果 iOS 上卡顿、安卓上点击失灵;或者用 position: fixed 做左侧导航,但在页面滚动时错位——本质是没处理好 scroll 和 touch 的事件穿透与层级关系。
- 左侧分类列表必须用
scroll-view包裹,并设scroll-y="true",禁用scroll-x(否则干扰右侧 swiper) - 右侧商品分类内容区用
swiper,设vertical="false"(横向)、current绑定当前索引,change事件同步左侧高亮 - 左右联动靠
current和scroll-into-view配合:右侧 swiper 切换时,用scroll-view的scrollIntoView方法滚动到对应id - 别忘了给每个左侧
view加唯一id(如id="cate-0"),否则scroll-into-view不生效
为什么不用 touchmove 手写侧滑逻辑
因为 uni-app 的 touchmove 在不同平台表现差异大:iOS 上容易触发页面回弹、安卓部分机型会吞掉第一次 touchstart、微信小程序里还可能和下拉刷新冲突。京东这类高交互场景,稳定性优先于“看起来更自定义”。
真实使用中,用户快速滑动分类时,手写逻辑常出现「滑过头没响应」「松手后自动跳回」「点击无反馈」,归根结底是 touchend 时机判断不准 + px 距离阈值设得不合理。
-
swiper内置防抖、惯性、边界回弹,且 uni-app 已对各端做了 patch - 如果真要微调动效,改
duration和interval就行,不用碰底层事件流 - 需要“吸顶”效果?在
scroll-view外层加position: sticky(H5 支持好,小程序需用uni.createSelectorQuery模拟)
scroll-view 滚动到指定分类的坑点
很多人写了 scroll-into-view="cate-2" 却没反应,不是语法错,而是三个隐藏条件没满足:
- 目标元素必须在
scroll-view内部,且不能被v-if动态销毁(要用v-show) -
scroll-view必须有明确高度(比如height: 60vh),不能靠内容撑开 - 首次渲染时,如果分类数据异步加载,
scroll-into-view会失效——得等this.$nextTick()后再调用scrollIntoView方法 - 小程序真机调试时,
scroll-into-view对中文 id 或带特殊字符的 id 不敏感,建议只用纯数字或字母组合(如cate-0)
性能关键:分类多时避免渲染爆炸
京东一级分类常超 20 个,二级三级嵌套更深。直接 v-for 全量渲染所有子项,首屏卡顿、内存飙升,尤其低端安卓机。
真正可行的做法是「按需渲染 + 预加载」:只渲染当前 swiper 页面 + 相邻一页的内容,其余用占位符;用户快滑到边缘时,提前 fetch 下一组数据并插入 DOM。
- 用
swiper的transitionend事件判断是否滑到边界,而不是依赖change - 每个分类区块用
name属性标记(如name="category-3"),便于后续动态ref操作 - 不要在
scroll-view里放图片,左侧导航只放文字+小图标;图片统一用懒加载指令v-lazy(需自行封装或引入uni-app官方 lazy 组件)
change 回调里手动 this.$refs.rightScroll.scrollTo(0, 0),而且这个 ref 必须绑定在 scroll-view 上,不是外层容器。










