left-slide-operation 左滑操作组件详解
前言
在移动端列表交互中,"左滑显示操作按钮"是一种非常常见且自然的交互模式。无论是微信聊天列表的左滑删除,还是 iOS 邮件的左滑归档,都体现了这一设计模式的实用性。
left-slide-operation 是一个轻量级的 uni-app 左滑操作组件,通过简单的手指滑动即可呼出隐藏在右侧的操作按钮,适用于列表删除、收藏、标记已读等场景。
功能特性
isSlide 属性全局或单项禁用滑动 | |
属性列表
'../../static/del_icon.png' | |||
'width: 50rpx; height: 50rpx;' | |||
事件列表
item | ||
{ lastSlideIndex, index, item } | ||
{ lastSlideIndex, item } | ||
{ index, item } |
快速开始
1. 引入组件
将 left-slide-operation 组件文件夹放入项目的 components/ 目录下,uni-app 会自动通过 easycom 模式识别该组件,无需手动引入。
2. 基础使用
<template><view><left-slide-operationv-for=”(item, index) in 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: [{ id: 1, name: '条目一' },{ id: 2, name: '条目二' }]}},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-operationv-for=”(item, index) in list”:key=”item.id”:itemData=”item”:index=”index”:operationImageSrc=”deleteIcon”operationImageStyle=”width: 44rpx; height: 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 个事件( itemTouchStart、itemTouchEnd、itemClickCallBack、operationCallBack)的触发情况
全局开关关键代码:
<switch:checked=”slideEnabled” @change=”toggleSlide” /><left-slide-operationv-for=”(item, index) in list”:isSlide=”slideEnabled”:itemData=”item”:index=”index”@operationCallBack=”onDelete”><!-- ... --></left-slide-operation>
实现原理
架构概览
┌────────────────────────────────────────┐│ <wrapper> ││ position: relative; overflow: hidden ││ ││ ┌──────────────────────────────┐ ││ │ <item-view> (slot) │ │ ← position: absolute; z-index: 3│ │ 通过 left 偏移实现滑动 │ │ transform: translateX(-100px)│ └──────────────────────────────┘ ││ ┌──────────┐ ││ │ <delete> │ │ ← position: absolute; right: 0│ │ 操作按钮 │ │ 初始隐藏在右侧屏幕外│ └──────────┘ │└────────────────────────────────────────┘
组件由两层视图构成:上层 <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 // 锁定在 -100pxthis.leftStyle = { left: (deleteBtn + left) + 'px' } // item-view 左移this.rightStyle = { left: left + 'px' } // delete 按钮跟出}}
滑动距离超过操作按钮宽度(100px)后锁定,防止过度滑动。公式推导:
当手指左滑 100px 时, left = -100item-view: left = 100 + (-100) = 0(保持在原位)delete按钮: left = -100px(从右侧跟出)
3. touchEnd — 状态确认与回弹
touchEnd(e, index) {if (this.left < this.deleteBtn) {this.left = -50this.leftStyle = { left: '-50px' } // item-view 半露出态this.rightStyle = { right: '0px' } // delete 回正uni.setStorageSync('lastSlideIndex', index)}}
状态管理
组件通过 uni.setStorageSync 将当前滑动项的 index 存入本地缓存,在 itemClick 和 touchStart 事件中会回传 lastSlideIndex,方便父组件管理多个列表项之间的互斥状态(同一时间只允许一项展开)。
滑动开关
isSlide 属性控制滑动行为:为 false 时,touchStart、touchMove、touchEnd 三个方法直接 return,不做任何处理,从而"禁用"滑动。
CSS 动画
所有位置变化均通过 CSS transition: all 0.5s 实现平滑过渡:
.item-view {position: absolute;left: 0;z-index: 3;transition: all 0.5s; // 平滑滑动动画}.delete {position: absolute;right: 0;transition: all 0.5s; // 按钮跟随动画}
注意事项
- 图标路径
: operationImageSrc默认值'../../static/del_icon.png'是相对于组件目录的路径,建议在使用时显式传入绝对路径(如/static/delete.png) - 按钮宽度
:组件内部 deleteBtn硬编码为100(px),与 CSS 中.delete的width: 100rpx对应。如需修改按钮宽度,需同步修改 JS 中的deleteBtn值 - 互斥滑动
:组件本身不管理多行互斥逻辑(同一时间只能展开一行),但提供了 lastSlideIndex供父组件实现 - 滚动冲突
:若列表在 scroll-view内,滑动操作可能与页面滚动冲突,建议根据实际场景调整
总结
left-slide-operation 是一个实现简洁、使用灵活的 uni-app 左滑操作组件。它通过原生 touch 事件实现了流畅的滑动动画,提供了丰富的属性和事件供开发者自定义,非常适合在列表类场景中快速集成"左滑删除"等交互功能。

组件代码已托管在 Gitee:
👉 https://gitee.com/hszcxl/TestUniapp/tree/left-slide-operation
夜雨聆风