uni-app swiper 设置 vertical 为 false 时,应该只响应左右滑动的手势
uni-app swiper 设置 vertical 为 false 时,应该只响应左右滑动的手势
| 开发环境 | 版本号 | 项目创建方式 |
|---|---|---|
| Windows | macOS Big Sur 11.2.3 | HBuilderX |
操作步骤:
- swiper 默认应该只响应左右滑动的手势
预期结果:
- swiper 设置 vertical 为 false 时,应该只响应左右滑动的手势
- swiper 设置 vertical 为 true 时,应该只响应上下滑动的手势
实际结果:
- swiper 没有任何手势控制
bug描述:
- swiper 设置 vertical 为 false 时,应该只响应左右滑动的手势
- swiper 设置 vertical 为 true 时,应该只响应上下滑动的手势
- 目前,配置成横向的时候,实际测试发现会响应上下滑动手势
- 对于 swiper-list 这种结构,会导致上下滑动时候,左右也会滑动
- 如果 swiper 在左右滑动的时候,会导致内部的list也在做滑动,体验很不好
更多关于uni-app swiper 设置 vertical 为 false 时,应该只响应左右滑动的手势的实战教程也可以访问 https://www.itying.com/category-93-b0.html
2 回复
根据你的描述,这确实是 uni-app 中 swiper 组件一个已知的交互问题。核心原因在于 swiper 组件(尤其在App端和部分小程序平台)的默认手势识别策略可能不够严格,没有将垂直滑动和水平滑动事件完全隔离。
当 vertical="false"(即横向模式)时,一个轻微的垂直方向手势分量也可能被误判为有效的滑动意图,从而触发翻页。这在与内部可垂直滚动的组件(如 scroll-view 或列表)嵌套时,体验冲突尤为明显。
直接的解决方案是使用 @touch 事件手动控制:
你可以通过捕获触摸事件,计算滑动的方向,并在非目标方向上阻止 swiper 的默认行为。
<template>
<swiper
:vertical="false"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
>
<!-- swiper-item 内容 -->
</swiper>
</template>
<script>
export default {
data() {
return {
startX: 0,
startY: 0,
isHorizontal: false // 标记当前是否为有效横向滑动
};
},
methods: {
handleTouchStart(e) {
this.startX = e.touches[0].clientX;
this.startY = e.touches[0].clientY;
this.isHorizontal = false;
},
handleTouchMove(e) {
if (this.isHorizontal) return; // 如果是横向滑动,则允许后续移动事件
const moveX = e.touches[0].clientX - this.startX;
const moveY = e.touches[0].clientY - this.startY;
// 计算滑动角度,如果更偏向垂直方向,则阻止事件(可根据需要调整阈值)
if (Math.abs(moveY) > Math.abs(moveX) * 1.5) { // 阈值示例
// 阻止 swiper 对此次滑动的响应,让内部列表滚动
// 注意:uni-app中无法直接e.preventDefault(),但可通过返回或标记来逻辑控制
this.isHorizontal = false;
// 如果需要,可以在这里通知子组件允许滚动
} else {
this.isHorizontal = true; // 标记为横向滑动,允许swiper翻页
}
},
handleTouchEnd() {
this.isHorizontal = false;
}
}
};
</script>


