10. 列表项左右滑动以展示隐藏操作按钮:uni-swipe-action
**用处:**在移动端开发中,屏幕空间寸土寸金。为了在不跳转页面的情况下展示更多操作选项,"左滑删除"或"左滑操作"已成为业界标准的交互模式。
在 uni-app 生态中,uni-swipe-action 是实现这一功能的官方推荐组件。它不仅支持左滑,还支持右滑,且兼容小程序和 App。
基本语法:


uni-swipe-action 的结构可以概括为"一个容器,多个子项"。
<uni-swipe-action>:外层容器,充当事件总线的角色,用于管理内部所有子项的开关状态。<uni-swipe-action-item>:具体的列表项,包裹内容区域和操作按钮区域。
核心属性:
1. uni-swipe-action-item 的关键属性:
right-options:右侧按钮配置数组。这是最常用的属性,用于定义滑出按钮的文字、样式和图标。- 数据结构:
[{ text: '删除', style: { backgroundColor: '#dd524d' } }]
- 数据结构:
left-options:左侧按钮配置数组(用法同右)。threshold:滑动阈值。比如设为100,表示滑动超过 100px 才会弹出按钮。disabled:是否禁用滑动。
2. 事件:
@click:当点击按钮时触发,回调参数中包含按钮的索引。@change:当滑动状态变化时触发(打开/关闭)。
基础示例:
下面实现一个经典的"左滑删除"列表项。
javascript
<template>
<view class="container">
<!-- 外层容器:用于收起其他已打开的项 -->
<uni-swipe-action>
<!-- 列表循环 -->
<uni-swipe-action-item
v-for="(item, index) in list"
:key="item.id"
:right-options="options"
@click="handleClick($event, index)"
@change="changeSwipe"
>
<!-- 正文内容区域 -->
<view class="content-box">
<text>{{ item.title }}</text>
<text class="info">{{ item.content }}</text>
</view>
</uni-swipe-action-item>
</uni-swipe-action>
</view>
</template>
<script>
export default {
data() {
return {
list: [
{ id: 1, title: '消息通知', content: '您有一条新的付款消息' },
{ id: 2, title: '系统更新', content: '新版本 v2.0 已发布' }
],
// 右侧按钮配置
options: [
{ text: '取消', style: { backgroundColor: '#C7C6CD' } },
{ text: '删除', style: { backgroundColor: '#DD524D' } }
]
};
},
methods: {
// 点击按钮回调
handleClick(e, index) {
const { content } = e; // content.text 可以判断点击了哪个按钮
if (content.text === '删除') {
uni.showModal({
title: '提示',
content: '确定删除吗?',
success: (res) => {
if (res.confirm) {
this.list.splice(index, 1);
uni.showToast({ title: '删除成功', icon: 'success' });
}
}
});
} else if (content.text === '取消') {
// 关闭当前项的滑动菜单(通常通过 ref 调用 close 方法,下文详述)
console.log('点击取消');
}
},
// 滑动状态变化
changeSwipe(e) {
console.log('当前状态:', e.open ? '已打开' : '已关闭');
}
}
};
</script>
<style>
.content-box {
width: 100%;
padding: 20rpx 30rpx;
background-color: #fff;
border-bottom: 1rpx solid #eee;
}
.info {
margin-left: 20rpx;
color: #888;
font-size: 24rpx;
}
</style>
企业开发中的实际应用场景
场景一:消息中心与邮件列表(左滑标为已读)
这是最常见的场景。用户向左滑动一条消息,可以快速"标为已读"、"置顶"或"删除",无需进入详情页操作。
javascript
// 动态配置 options
const msgOptions = [
{ text: '置顶', style: { backgroundColor: '#007AFF' } },
{ text: '标为已读', style: { backgroundColor: '#4CD964' } },
{ text: '删除', style: { backgroundColor: '#DD524D' } }
];
场景二:购物车与订单管理(批量操作)
在电商 App 的订单列表中,左滑订单卡片可以进行"删除订单"或"联系客服"操作。
特别之处 :此时通常需要配合 uni-swipe-action 的实例方法,确保用户滑开一个新的订单时,上一个滑开的订单自动关闭,避免界面混乱。
场景三:自定义复杂交互(如滑动解锁)
除了列表操作,有些 App 会利用 threshold 属性实现"滑动解锁"或"滑动确认收款"功能,将整个屏幕宽度作为滑动区域,滑到底部触发事件。
注意事项:
在使用 uni-swipe-action 时,新手常会遇到以下问题:
(1) 按钮点击后菜单不自动关闭
现象 :用户点击了"删除",列表更新了,但滑动菜单依然处于打开状态,或者点击"取消"后菜单没关。
解决方案 :需要通过 ref 获取组件实例并调用 close() 方法。
html
<uni-swipe-action ref="swipeAction">
<uni-swipe-action-item ref="swipeItem">...</uni-swipe-action-item>
</uni-swipe-action>
javascript
// 点击事件中
this.$refs.swipeItem.close();
// 或者关闭所有(推荐在列表场景下,点击任意按钮后关闭所有)
this.$refs.swipeAction.closeAll();
(2) 嵌套在 scroll-view 中的冲突
现象 :当页面也是可滚动时,用户想左滑,结果手指稍微偏上偏下一点,就变成了列表上下滚动,导致滑动很难触发。
解决:
uni-swipe-action内部已处理了部分触摸事件冲突。- 尽量保证滑动区域(content-box)有一定的高度(如 100rpx 以上),方便用户操作。
- 如果是在微信小程序端,可以使用
enable-flex属性开启 flex 布局以兼容部分机型。
(3) 样式覆盖问题
现象 :默认的按钮样式(如宽度、字体大小)不符合设计稿要求。
解决 :不要尝试去修改 uni-swipe-action-item 内部 class,因为它使用了 shadow-dom 或原生组件。请务必通过 right-options 中的 style 对象来配置样式,例如:
javascript
{
text: '删除',
style: {
backgroundColor: '#DD524D',
fontSize: '28rpx', // 仅部分平台支持
width: '100px' // 部分平台支持自定义宽度
}
}
(4) 动态数据更新导致的状态错乱
现象 :在列表中使用 v-for 循环,当删除某一项后,新的一项继承了上一项的打开状态。
解决 :确保在删除数据逻辑之前,先调用 close() 关闭菜单,或者给 uni-swipe-action-item 绑定唯一的 :key,且该 key 在删除操作后保持稳定。