最稳妥的起点是直接使用 uni-swipe-action 组件,而非 uni-list + uni-list-item;它专为多端侧滑设计,需外层包裹并配置 right 数组、唯一 content 值、:key;H5 不支持 right-width,App 端需手写 touch 逻辑优化性能,购物车场景须注意 close()、响应式更新及真机兼容性。

uni-swipe-action 是最稳妥的起点
直接用 uni-list + uni-list-item 永远不会触发侧滑菜单——它只是样式容器,没手势逻辑。必须换 uni-swipe-action,它是 uni-app 官方为多端侧滑交互专门设计的组件,App、小程序、H5 都能跑通。
关键实操点:
- 每个列表项外层必须包一层
<uni-swipe-action>,再套<uni-swipe-action-item right="[{ content: '删除' }]"> -
right数组里每个按钮要带唯一content值,比如content="delete_${item.id}",否则@click回调拿不到准确目标 - 别省略
:key="item.id",否则 Vue diff 会复用 DOM,删错项、滑动状态残留都是常见后果 - H5 端不支持自定义菜单宽度(
right-width属性无效),真要兼容 H5,建议加个平台判断,H5 改用点击「…」弹出操作菜单
App 端 swipe-action 不跟手?得手写 touch 位移
在 App(iOS/Android)里,uni-swipe-action 实际是模拟滑动,不是调用原生侧滑能力,所以卡顿、回弹延迟、和滚动冲突是常态。真要顺滑,必须自己监听 touchstart/touchmove/touchend,用 transform: translateX() 控制位移。
核心注意点:
- 用
ref拿到当前项 DOM 元素,避免操作错节点 -
touchmove中立刻设transition: none,否则动画会打断实时跟随 - 松手后判断:若
Math.abs(offsetX) > 60,才执行吸附动画;否则回弹归零 - 必须加
will-change: transform或启用硬件加速(translateZ(0)),否则 iOS 下尤其卡 - 千万别在
scroll-view内使用——它的滚动拦截机制会让 touch 事件失效
购物车场景下容易被忽略的三个坑
购物车不是普通列表,多选、数量变更、价格重算都耦合在一起,侧滑删除一错就连锁反应。
高频翻车点:
- 删除前不调
swipeAction.close():用户划开一个,又点另一个,两个同时展开,UI 错乱且可能误删 - 数组更新用
splice(i, 1)而非filter:Vue 2 下splice是响应式,但 Vue 3 的ref数组需用cartList.value = cartList.value.filter(...)才触发更新 - 微信小程序真机点不中删除按钮:检查父容器是否加了
overflow: hidden(cover-view 渲染会被裁),或有没有悬浮广告 banner 盖住滑动区域(哪怕透明也挡事件)
为什么别自己从头写滑动手势
看起来只是几个 touch 事件加个位移计算,但实际落地时,各端差异会把你拖垮。
典型问题:
- 微信小程序真机上
touchmove经常被拦截,表现为“划了但没反应”,iOS 和 Android WebView 对touch-action: none支持也不一致 - 滑动角度没过滤:手指轻微下拉也会触发左滑,得算角度(
Math.abs(angle) > 15)再判断 - px/rpx 混用:不同屏幕宽度下阈值该设多少?120px 在 iPhone 上刚好,在安卓大屏上可能太小
- 橡皮筋效果干扰:iOS 页面边缘下拉刷新会吃掉部分 touch 事件,导致滑动起始坐标不准
这些细节 uni-swipe-action 内部已做适配,除非你明确需要定制动画曲线或与原生侧滑深度集成,否则没必要重复踩一遍。



















