官方文档
问题描述:
当项目需要开发列表滑选删除功能时,可以借助uni-app 扩展组件 uni-swipe-action实现
将内容区域向左滑动,显示右侧删除按钮;当点击内容区域或右侧删除按钮时,组件都会自动收缩
有时候,点击删除按钮,弹出对话框询问用户是否确认删除,此时删除按钮不需要隐藏。如何实现?
解决方案
一、使用变量控制开关 (了解)
官方示例中,通过 控制show 属性取值 left/right/none,实现组件左右内容的显示与隐藏,需要配合 auto-close = false 进行使用
实现思路:
1、给内容区域绑定touchstart、touchend事件
2、用户滑动内容区域,根据滑动的差值,判断是进行左滑或右滑
3、如果是左滑,设置当前 uni-swipe-action-item 的 show 属性为 right;如果是右滑,设置当前 uni-swipe-action-item 的 show 属性为 left
4、因为设置了auto-close = false ,滑动过程中,组件并不会跟随手指实时滑动,用户体验不太友好,了解即可
二、使用 disabled + 触摸事件实现
实现思路:
1、通过 uni-swipe-action-item 的 disabled 属性,控制当前组件是否会自动收缩。为true时不自动收缩,false时自动收缩
2、当用户左滑时,设置当前项的disabled为true,此时点击右侧删除按钮就不会隐藏了
3、当用户右滑或点击内容区域时,设置当前项的disabled为false,当前项会跟随手指实时滑动,滑动结束后隐藏删除按钮
关键步骤:
1、创建变量 disabledItem , 用来存放不可操作列表项的 id
2、给内容区域绑定 touchstart、touchend 事件
3、touchstart触发时:
(1)重置 disabledItem = -1(此时,所有列表项disabled均为false,元素会跟随手指实时滑动)
(2)记录滑动开始水平方向坐标 startX
4、touchend 触发时:
(1)获取滑动结束水平方向坐标 endX
(2)获取 startX 和 endX 的差值 disX
(3)如果 disX > 0,代表用户进行了左滑,设置 disabledItem 为 当前项 id
(4)如果disX <= 0,代表用户进行了右滑或点击内容区域,使用组件 closeAll() 方法关闭打开的列表项
代码示例:
html:
<uni-swipe-action ref="slide">
<!-- 列表项 -->
<uni-swipe-action-item
v-for="item in historyList"
:key="item.id"
:disabled="disabledItem == item.id">
<!-- 列表内容区域 -->
<view
class="history-text"
@click="contentClick(item.id)"
@touchstart="touchstart"
@touchend="e => touchend(e, item.id)">
<!-- ... -->
</view>
<!-- 右侧删除按钮 -->
<template v-slot:right>
<view class="right-content" @click="rightClick">
<view class="icon-delete"></view>
</view>
</template>
</uni-swipe-action-item>
</uni-swipe-action>
js:
export default {
data() {
return {
startX: 0, // 滑动起点坐标
disabledItem: -1, // 不可操作的会话id
historyList: [] // 历史记录列表
}
},
methods: {
// 内容区域滑动
touchstart(e) {
this.startX = e.touches[0].clientX
this.disabledItem = -1
},
// 内容区域滑动结束
touchend(e, id) {
const endX = e.changedTouches[0].clientX
const disX = this.startX - endX
if (disX > 0) {
this.disabledItem = id
} else {
this.$refs.slide.closeAll()
}
},
// 点击内容区域
contentClick(id) {
// do something
},
// 点击右侧区域
rightClick() {
// do something
}
}
}