<div>
<move-left v-if="list.length>0" :list="list" :del_width="60" @del="del">
<template v-slot:line="scope">
<div class="row">
{
{scope.item.name}}
div>
template>
<template v-slot:del>
<div class="del">删除div>
template>
move-left>
div>
del_width属性为‘删除按钮’的宽度,
list为数据列表
del为删除的事件
你可以在插槽中定义你自己的行内容样式以及删除按钮的样式
<script>
import moveLeft from '../components/moveLeft'
export default {
name: 'index',
data () {
return {
list:[],
}
},
components:{
moveLeft
},
mounted () {
this.loadList()
},
methods: {
loadList(){
this.list=[
{
name:'土豆'},
{
name:'玉米'},
{
name:'花生'},
{
name:'菠菜'},
]
},
del(item){
this.$dialog.confirm({
title: '提示',
message:'是否删除'+item.name+'?',
}).then(() => {
this.loadList()
}).catch(() => {
this.loadList()
});
},
},
}
</script>
<template>
<div>
<template v-for="(item,index) in list">
<div
@click.stop="deleteCard(item,index)"
@touchstart="touchstart($event,index)"
@touchmove="touchmove($event,index)"
@touchend="touchend($event,index)"
class="v relative "
style="overflow: hidden;">
<div class="v relative z-index10" :style="{
transform: 'translateX('+item.move+'px)'}">
<slot :item="item" name="line">slot>
div>
<div class="del">
<slot name="del">slot>
div>
div>
template>
div>
template>
<script>
export default {
name: 'moveLeft',
props:{
list:{
type:Array,
default:[]
},
del_width:{
type:Number,
default: 0
}
},
data(){
return{
moveIndex:0,
move:0,
startX:0,
endX:0,
moveX:0,
disX:0,
}
},
methods:{
touchstart(e,index){
e = e || event
if(e.touches.length == 1){
this.moveIndex=index
this.startX=e.touches[0].clientX
}
},
touchmove(e,index){
if(this.moveIndex!=index){
return
}
e = e || event
let width=this.del_width
if(e.touches.length == 1){
this.moveX=e.touches[0].clientX
this.disX=this.startX-this.moveX
if(this.disX<=0){
this.list[index].move=0
}else if(this.disX>0){
this.list[index].move=this.disX*(-1)
this.list[index].show=true
if(Math.abs(this.list[index].move)>width){
this.list[index].move=width*(-1)
this.list[index].show=true
for(let i=0;i<this.list.length;i++){
if(i!=this.moveIndex){
this.list[i].move=0
this.list[i].show=false
}
}
}
}
this.$forceUpdate()
}
},
touchend(e,index){
if(this.moveIndex!=index){
return
}
e = e || event
let width=this.del_width
if(e.changedTouches.length == 1){
this.endX=e.changedTouches[0].clientX
this.disX=this.startX-this.endX
if(this.disX<(width/2)){
this.list[index].move=0
}else{
this.list[index].move=width*(-1)
this.list[index].show=true
for(let i=0;i<this.list.length;i++){
if(i!=this.moveIndex){
this.list[i].move=0
this.list[i].show=false
}
}
}
this.$forceUpdate()
}
},
deleteCard(item,index){
if(item.show){
this.$emit('del',item)
}
},
},
mounted () {
if(this.list.length>0){
this.list.forEach(item=>{
item.move=0;
item.show=false
})
}
}
}
script>
<style scoped>
.v{
width: 100%;
float: left;
}
.relative{
position: relative;
}
.z-index10{
z-index:20;
}
.del{
position: absolute;
z-index: 10;
right:0;
min-width: 60px;
height:100%;
}
style>