实现的思路:走了很多弯路,参考了别人的实现方法。左滑删除,就是监听滑动的事件,小程序api中有提供到touchstart和touchmove的事件。当滑动超过一定的距离,触发事件。把删除按钮显示出来,反之。
其实难点是在以什么的方式实现删除按钮的显示和隐藏。源码在最下
(1)弯路:
一开始是想到用scroll-view的组件来实现的。交互效果能实现了,但是@scroll,监听滑动事件时,无法动态改变scroll-left,就无法实现滑动一定距离就显示隐藏按钮。
这里还踩了一个scroll-view的坑,就是设置了scroll-x,但是还无法左右滑动。
https://blog.csdn.net/sinat_26521835/article/details/80358280
平时我们对一组元素进行横向排列时,常用display:flex、float:left或行内元素性质的办法.但是,在小程序的这个组件里display:flex与float:left是行不通的,在这里,我们要使用display:inline-block利用行内元素性质来进行横向排列,并且设置为white-space:nowrap才有效果
(2)弯路:
放弃用scroll-view,直接用普通的div来实现。我就想到直接把删除键放到滑动内容的右侧
手指向左滑动一定距离,内容向左滑动隐藏一部分,然后删除按钮向左滑动显示。就想到用浮动或者display:flex来布局。效果是实现了,但是却很别扭。左滑的时候内容是向左隐藏了一部分,但是删除按钮在向左显示时,‘删除’2字也会动画的显示,很是奇怪。
最终,参考别人的布局方式,用position来实现。
就是滑动的时候,只是内容在滑动(动态设置content的right),跟删除按钮无关,
<template>
<div
class="slide"
@touchstart="touchS"
@touchmove="touchM"
>
<div class="contents_wrapper" :style="'right:' del'px'">
<slot >
<!-- <div class="contents">内容1</div> -->
</slot>
</div>
<div class="delete" @click="delt">删除</div>
</div>
</template>
<script>
export default {
name:'slide',//左滑删除
data() {
return {
clientX1:'',//滑动开始位置
clientX2:'',
del:0,//内容初始的right距离
btnWidth:80//删除按钮宽度
}
},
methods: {
touchS(e){
this.clientX1=e.clientX
},
touchM(e){
this.clientX2=e.clientX
let disX=this.clientX1-this.clientX2
if (disX == 0 || disX < 0) {//如果移动距离小于等于0,说明向右滑动,文本层位置不变
this.del = 0;
}
if (disX >= this.btnWidth) {
//控制手指移动距离最大值为删除按钮的宽度
this.del =this.btnWidth;
}
},
delt(){
console.log(8888)
}
},
}
</script>
<style scoped>
.slide{
width: 100%;
position: relative;
height: 120px;
}
.contents_wrapper{
width: 100%;
height: 100%;
position: absolute;
transition: right 0.3s ease-in-out;
z-index: 99;
background: #fff
}
.contents{
width: 100%;
}
.delete{
color:#fff;
height: 100%;
text-align: center;
width:80px;
background: red;
line-height: 120px;
position: absolute;
right:0;
}
</style>
效果已经实现了,但是到对接接口的时候,发现这个组件不能动态插入数据就是 mpvue中的slot不支持变量
坑死人了!!
然后就直接把组件的代码放到页面中,问题又来了,因为不是组件引入。每滑动一个slide,其他的slide都会相应的滑动。因为它们是根据del来改变right的。
于是为了能对分别对不同的slide进行处理,要给每个slide给一个标志位。
思路1:可以这条数据的index来进行标记,当slide 的index和data中的index相等时,添加toslide的样式
<template>
<div
class="slide"
@touchstart="touchS"
@touchmove="touchM(e,index)"
v-for="(item,index) of valueData"
:key="index"
>
<div :class=["contents_wrapper",{toslide:index==this.index]]>
</div>
<div class="delete" @click="delt">删除</div>
</div>
</template>
<script>
export default {
name:'slide',//左滑删除
data() {
return {
index:'',//初始状态的index
clientX1:'',//滑动开始位置
clientX2:'',
del:0,//内容初始的right距离
btnWidth:80//删除按钮宽度
}
},
methods: {
touchS(e){
this.clientX1=e.clientX
},
touchM(e,index){
this.cli