乐于分享
好东西不私藏

uniapp左滑删除组件

uniapp左滑删除组件

left-slide-operation 左滑操作组件详解

前言

在移动端列表交互中,"左滑显示操作按钮"是一种非常常见且自然的交互模式。无论是微信聊天列表的左滑删除,还是 iOS 邮件的左滑归档,都体现了这一设计模式的实用性。

left-slide-operation 是一个轻量级的 uni-app 左滑操作组件,通过简单的手指滑动即可呼出隐藏在右侧的操作按钮,适用于列表删除、收藏、标记已读等场景。

功能特性

特性
说明
🎯 左滑显示
手指向左滑动,右侧露出操作按钮
🎨 自定义操作
支持自定义操作按钮图标、尺寸
🔒 滑动控制
可通过 isSlide 属性全局或单项禁用滑动
📦 插槽支持
通过 slot 自定义列表项内容
📡 事件系统
完整的 touch 生命周期事件回调
💾 状态记忆
通过 localStorage 自动记录最后滑动项

属性列表

属性名
类型
默认值
说明
itemData
Object
{}
列表项的数据对象
index
Number
0
列表项的下标索引
operationImageSrc
String
'../../static/del_icon.png'
操作按钮的图标路径
operationImageStyle
String
'width: 50rpx; height: 50rpx;'
操作按钮的样式字符串
isSlide
Boolean
true
是否允许滑动操作

事件列表

事件名
回调参数
触发时机
@operationCallBack
item
 — 当前项数据
点击右侧操作按钮时
@itemClickCallBack
{ lastSlideIndex, index, item }
点击列表项时
@itemTouchStart
{ lastSlideIndex, item }
手指开始触摸时
@itemTouchEnd
{ index, item }
滑动结束/手指抬起时

快速开始

1. 引入组件

将 left-slide-operation 组件文件夹放入项目的 components/ 目录下,uni-app 会自动通过 easycom 模式识别该组件,无需手动引入。

2. 基础使用

<template> <view> <left-slide-operation v-for=”(item, indexin list :key=”item.id” :itemData=”item” :index=”index” :operationImageSrc=”deleteIcon” @operationCallBack=”onDelete” > <!-- 自定义列表项内容 --> <viewclass=”my-item”> <text>{{ item.name }}</text> </view> </left-slide-operation> </view></template><script>export default { data() { return { deleteIcon'/static/del_icon.png', list: [ { id1name'条目一' }, { id2name'条目二' } ] } }, methods: { onDelete(item) { this.list = this.list.filter(i => i.id !== item.id) } }}</script>

示例详解

本组件提供了 3 个完整的示例页面,涵盖从基础到高级的各类用法:

示例1:基础用法 — 列表左滑删除

路径:pages/cxl-left-slide-demo/demo01-basic

最常用的使用场景。展示了一个类似聊天列表的 UI,每个列表项包含头像、名称、描述和时间。手指左滑每一项可露出删除按钮,点击按钮即可从列表中移除该项。

关键代码:

<left-slide-operation v-for=”(item, indexin list :key=”item.id” :itemData=”item” :index=”index” :operationImageSrc=”deleteIcon” operationImageStyle=”width: 44rpxheight: 44rpx;” @operationCallBack=”onDelete”> <viewclass=”list-item”> <!-- 自定义列表项 UI --> </view></left-slide-operation>

示例2:自定义操作 — 多种操作按钮

路径:pages/cxl-left-slide-demo/demo02-custom

展示了三种不同的自定义场景:

  • 场景A — 大号删除按钮
    :通过 operationImageStyle="width: 60rpx; height: 60rpx;" 自定义按钮尺寸
  • 场景B — 收藏切换
    :动态切换 operationImageSrc,实现收藏/取消收藏的图标变化
  • 场景C — 带背景色操作区
    :展示如何通过修改组件 CSS 实现不同风格

收藏切换关键代码:

<left-slide-operation :operationImageSrc=”item.starred ? starIcon : unstarIcon @operationCallBack=”onToggleStar”> <!-- ... --></left-slide-operation>
onToggleStar(item) { item.starred = !item.starred // 切换收藏状态,图标随之变化}

示例3:动态控制 — 编程式操作

路径:pages/cxl-left-slide-demo/demo03-control

展示了三个高级用法:

  • 场景A — 全局开关
    :通过 <switch> 组件绑定 isSlide 属性,一键开启/关闭所有列表项的滑动功能
  • 场景B — 单项控制
    :每个列表项通过自身的 slideable 字段独立控制是否可滑动(如"锁定条目不可删")
  • 场景C — 事件日志
    :实时监听并展示 4 个事件(itemTouchStartitemTouchEnditemClickCallBackoperationCallBack)的触发情况

全局开关关键代码:

<switch:checked=”slideEnabled” @change=”toggleSlide” /><left-slide-operation v-for=”(item, indexin list :isSlide=”slideEnabled” :itemData=”item” :index=”index” @operationCallBack=”onDelete”> <!-- ... --></left-slide-operation>

实现原理

架构概览

┌────────────────────────────────────────┐│ <wrapper> ││ position: relative; overflow: hidden ││ ││ ┌──────────────────────────────┐ ││ │ <item-view> (slot) │ │ ← position: absolute; z-index3│ │ 通过 left 偏移实现滑动 │ │ transform: translateX(-100px)│ └──────────────────────────────┘ ││ ┌──────────┐ ││ │ <delete> │ │ ← position: absolute; right0│ │ 操作按钮 │ │ 初始隐藏在右侧屏幕外│ └──────────┘ │└────────────────────────────────────────┘

组件由两层视图构成:上层 <item-view> 承载用户自定义内容(通过 slot),下层 <delete> 承载操作按钮。两者均使用 position: absolute 定位,通过动态修改 left 样式实现滑动动画。

核心交互流程

整个交互分为 3 个阶段:

1. touchStart — 记录起始点

touchStart(e, index) { this.Tactive = index // 标记当前激活项 this.startX = e.touches[0].clientX // 记录手指 X 坐标}

2. touchMove — 实时计算偏移

touchMove(e, index) { this.left = e.touches[0].clientX - this.startX // 计算滑动距离 if (this.left < -this.deleteBtn) { // 超过按钮宽度(100px) this.left = -this.deleteBtn // 锁定在 -100px this.leftStyle = { left: (deleteBtn + left) + 'px' } // item-view 左移 this.rightStyle = { left: left + 'px' } // delete 按钮跟出 }}

滑动距离超过操作按钮宽度(100px)后锁定,防止过度滑动。公式推导:

  • 当手指左滑 100px 时,left = -100
  • item-view
    left = 100 + (-100) = 0(保持在原位)
  • delete
     按钮:left = -100px(从右侧跟出)

3. touchEnd — 状态确认与回弹

touchEnd(e, index) { if (this.left < this.deleteBtn) { this.left = -50 this.leftStyle = { left: '-50px' } // item-view 半露出态 this.rightStyle = { right: '0px' } // delete 回正 uni.setStorageSync('lastSlideIndex', index) }}

状态管理

组件通过 uni.setStorageSync 将当前滑动项的 index 存入本地缓存,在 itemClick 和 touchStart 事件中会回传 lastSlideIndex,方便父组件管理多个列表项之间的互斥状态(同一时间只允许一项展开)。

滑动开关

isSlide 属性控制滑动行为:为 false 时,touchStarttouchMovetouchEnd 三个方法直接 return,不做任何处理,从而"禁用"滑动。

CSS 动画

所有位置变化均通过 CSS transition: all 0.5s 实现平滑过渡:

.item-view { position: absolute; left0; z-index3; transition: all 0.5s; // 平滑滑动动画}.delete { position: absolute; right0; transition: all 0.5s; // 按钮跟随动画}

注意事项

  1. 图标路径
    operationImageSrc 默认值 '../../static/del_icon.png' 是相对于组件目录的路径,建议在使用时显式传入绝对路径(如 /static/delete.png
  2. 按钮宽度
    :组件内部 deleteBtn 硬编码为 100(px),与 CSS 中 .delete 的 width: 100rpx 对应。如需修改按钮宽度,需同步修改 JS 中的 deleteBtn 值
  3. 互斥滑动
    :组件本身不管理多行互斥逻辑(同一时间只能展开一行),但提供了 lastSlideIndex 供父组件实现
  4. 滚动冲突
    :若列表在 scroll-view 内,滑动操作可能与页面滚动冲突,建议根据实际场景调整

总结

left-slide-operation 是一个实现简洁、使用灵活的 uni-app 左滑操作组件。它通过原生 touch 事件实现了流畅的滑动动画,提供了丰富的属性和事件供开发者自定义,非常适合在列表类场景中快速集成"左滑删除"等交互功能。

组件代码已托管在 Gitee:

👉 https://gitee.com/hszcxl/TestUniapp/tree/left-slide-operation