uniapp结合movable-area与movable-view实现拖拽功能

前言

因为公司业务开发需要拖拽功能。

ps:该功能只能针对高度一致的,如果高度不一致需要另外二开

演示

开始

javascript 复制代码
<template>
  <view style="height: 100%;">
    <movable-area :style="{'width': '100%', 'height': allHeight + 'px'}">
      <movable-view
        v-for="(item, index) in list"
        :key="item.id"
        :x="0"
        :y="item.y"
		:style="{'height': itemHeight + 'px', 'width': '100%',}"
        direction="all"
        @touchstart="handleDragStart(index)"
	   @change="handleMoving(index, $event)"
	   @touchend="handleDragEnd"
        class="movable-view"
      >
        <!-- 这里可以放置步骤的详细内容 -->
        <view style="background-color: aqua; padding: 20rpx 0;">{{ item.desc }}</view>
      </movable-view>
    </movable-area>
  </view>
</template>

<script>
export default {
  data() {
    return {
		list: [],
		cloneList: [],
	  
		activeIndex: -1, // 选中
		oldIndex: -1,
	  
		moveToIndex: -1, // 移动
	  
		allHeight: 300,
	  
		itemHeight: 50
    };
  },
  
  created() {
		for(let i = 0; i < 12; i ++) {
			let info = {
				  id: i,
				  desc: '测试' + i
			}
			this.list.push(info)
		}
		this.allHeight = 12 * this.itemHeight
		this.initList(this.list)
  },
  
  methods: {
    deepCopy(source) {
    	return JSON.parse(JSON.stringify(source));
    },
	
	initList(list=[]){
        const newList = this.deepCopy(list);
        this.list = newList.map((item, index) => {
            return {
                ...item,
                y: index * this.itemHeight,
                key: Math.random() + index
            };
        });
        //拷贝一份初始list值
        this.cloneList = this.deepCopy(this.list);
    },
	
	// 拖拽开始
	handleDragStart(index) {
		this.activeIndex = index;
		this.oldIndex = index;
	},
	handleMoving(index, e){
		if (e.detail.source !== 'touch') return;
		const { x, y } = e.detail;
		const currentY = Math.floor((y + this.itemHeight / 2) / this.itemHeight);

	  
		this.moveToIndex = Math.min(currentY, this.list.length - 1);
	
	  //更新移动后的位置
	  if (this.oldIndex !== this.moveToIndex && this.oldIndex !== -1 && this.moveToIndex !== -1) {
	    const newList = this.deepCopy(this.cloneList);
	    //交换位置
	    newList.splice(this.moveToIndex, 0, ...newList.splice(this.activeIndex, 1));
	
	    this.list.forEach((item, index) => {
	       if (index !== this.activeIndex) {
	         const itemIndex = newList.findIndex(val => val.id === item.id);
	         item.y = itemIndex*this.itemHeight
	       }
	    });
	    this.oldIndex = this.moveToIndex;
	  }
	},
	handleDragEnd(e) {
		if (this.moveToIndex !== -1 && this.activeIndex !== -1 && this.moveToIndex !== this.activeIndex) {
			  this.cloneList.splice(this.moveToIndex, 0, ...this.cloneList.splice(this.activeIndex, 1));
		}
	
		// 重新排序下更新后的位置。
		this.initList(this.cloneList);
		
		this.activeIndex = -1;
		this.oldIndex = -1;
		this.moveToIndex = -1;
	},
  },
};
</script>

<style>
.movable-area {

}

.movable-view {

}
</style>
相关推荐
Swift社区20 小时前
H5 与 ArkTS 通信的完整设计模型
uni-app·harmonyos
小溪彼岸1 天前
uni-app小白从0开发一款鸿蒙Next应用到上线
uni-app·harmonyos
一颗小青松1 天前
uniapp app端使用uniCloud的unipush
uni-app
cngm1101 天前
uniapp+springboot后端跨域以及webview中cookie调试
spring boot·后端·uni-app
iOS阿玮2 天前
“死了么”App荣登付费榜第一名!
uni-app·app·apple
wendycwb2 天前
uni-app 在真机中canvas绘制的元素悬浮,内容不随父组件滚动问题
uni-app
frontend_frank2 天前
脱离 Electron autoUpdater:uni-app跨端更新:Windows+Android统一实现方案
android·前端·javascript·electron·uni-app
三天不学习2 天前
UniApp三端实时通信实战:SignalR在H5、APP、小程序的差异与实现
微信小程序·uni-app·signalr
念你那丝微笑2 天前
uView Plus + Vue3 + TypeScript + UniApp 正确引入 UnoCSS(避坑版)
vue.js·typescript·uni-app
念你那丝微笑2 天前
vue3+ts在uniapp项目中实现自动导入 ref 和 reactive
vue.js·typescript·uni-app