移动端数组拖拽排序

移动端数组拖拽排序


在这里插入图片描述

<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);
				});
       // console.log('sortList',sortList);
				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>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值