移动端数组拖拽排序
<template>
<view class="drag-box">
<scroll-view :scroll-top="0" :scroll-y="isTouchMove"
:show-scrollbar="true" class="drag-and-drop-sort-B" :style="{
height:(windowHeight*0.8)+'px'
}">
<view
v-for="(item,index) in dataList"
:key="index"
:style="{
top: item.top +'px',
height: (itemHeight - 1)+'rpx',
lineHeight: (itemHeight - 1)+'rpx'
}"
class="drag-item"
:class="{'drag-active': item.isActive}"
@longtap="longtap(item)"
@touchstart="touchstart"
@touchmove="touchmove"
@touchend="touchend(item)">
{{ item.tableTitle?item.tableTitle:item.labelName}}
</view>
</scroll-view>
</view>
</template>
<script>
export default {
props: {
list: {
type: Array,
default: () => []
},
itemHeight: {
type: [Number],
default: 70
},
windowHeight: {
type: [Number],
default: 300
}
},
data() {
return {
activeItem: null,
isDrag: false,
dragTargetY: 0,
dataList: [],
sortIndexList: [],
isTouchMove:true,
}
},
watch: {
list: {
immediate: true,
deep: true,
handler (list) {
this.setList(list)
}
}
},
created(){
},
methods: {
touchstart(e){
this.dragTargetY = e.touches[0].pageY;
},
longtap(item){
this.activeItem = item;
this.isDrag = true;
item.isActive = true;
this.isTouchMove=false
},
touchmove(e){
if(!this.isDrag){
return
}
let newY = e.touches[0].pageY;
let d = newY - this.dragTargetY;
console.log('d',d);
this.activeItem.top += d;
let prevIndex = this.sortIndexList[this.activeItem.index] - 1;
let nextIndex = this.sortIndexList[this.activeItem.index] + 1;
if (prevIndex >= 0 && d < 0){
let item = this.getItemByIndex(prevIndex);
if (this.activeItem.top < item.top){
this.swapArray(item);
}
}else if (nextIndex < this.list.length && d > 0) {
let item = this.getItemByIndex(nextIndex);
if (this.activeItem.top > item.top){
this.swapArray(item);
}
}
this.dragTargetY = newY;
},
touchend(item){
if(!this.isDrag){
return
}
this.isTouchMove=true
this.isDrag = false;
item.isActive = false;
this.activeItem.top = this.sortIndexList[this.activeItem.index] * this.rowHeight;
let sortList = [];
Array(this.dataList.length).fill(0).forEach((v,index)=>{
let tempObj = this.deepClone(this.getItemByIndex(index));
delete tempObj.isActive;
delete tempObj.top;
delete tempObj.index;
sortList.push(tempObj);
});
this.$emit('sortChange', sortList);
},
getItemByIndex(index){
for (let i = 0;i < this.sortIndexList.length;i++){
if (this.sortIndexList[i] === index){
return this.dataList[i];
}
}
return null;
},
swapArray(item) {
let index = this.sortIndexList[this.activeItem.index];
this.sortIndexList[this.activeItem.index] = this.sortIndexList[item.index];
this.sortIndexList[item.index] = index;
item.top = index * this.rowHeight;
this.count = 0;
},
setList(list){
this.dataList = list.map((item, index) => {
this.sortIndexList.push(index);
return {
...item,
isActive: false,
top: index * this.rowHeight,
index: index
}
})
},
deepClone(obj){
if(!(typeof obj=='object'&&obj)){
return obj
}
let copyObj = obj instanceof Array ?[]:{}
for(let key in obj){
copyObj[key]=this.deepClone(obj[key])
}
return copyObj
}
},
mounted() {
},
computed:{
rowHeight(){
const res = uni.getSystemInfoSync();
let screenWidth = res.screenWidth;
if (this.itemHeight){
return this.itemHeight*screenWidth/750;
}else{
return 0;
}
}
}
}
</script>
<style lang="scss">
.drag-box{
width: 100%;
height: 100%;
position: relative;
}
.drag-item{
width: 100%;
text-align: center;
transition: all 0.2s;
background-color: #fff;
z-index: 1;
border: 1rpx dashed #F5F5F5;
position: absolute;
}
.drag-active{
box-shadow: 0 8px 20px 0 #e6e6e6;
transform: scale(1.1);
z-index: 9 !important;
transition: box-shadow .2s, transform .2s, top 0s !important;
}
</style>