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>
相关推荐
郑州光合科技余经理5 小时前
可独立部署的Java同城O2O系统架构:技术落地
java·开发语言·前端·后端·小程序·系统架构·uni-app
雪芽蓝域zzs5 小时前
uniapp 取消滚动条
uni-app
2401_865854887 小时前
Uniapp和Flutter哪个更适合企业级开发?
flutter·uni-app
雪芽蓝域zzs7 小时前
uniapp 省市区三级联动
前端·javascript·uni-app
总爱写点小BUG7 小时前
UniApp 图标方案终极排坑:告别 FontClass,拥抱真 SVG 组件化
前端框架·uni-app
Rysxt_1 天前
UniApp获取安卓系统权限教程
android·uni-app
木子啊1 天前
ProCamera 智能水印相机解决方案 (UniApp)
数码相机·uni-app·水印相机·小程序水印
木子啊1 天前
Uni-app跨页面通信三剑客
前端·uni-app·传参
Rysxt_2 天前
UniApp五大UI框架与uni-ui核心区别对比
uni-app·uni-ui
2501_915918412 天前
HTTPS 代理失效,启用双向认证(mTLS)的 iOS 应用网络怎么抓包调试
android·网络·ios·小程序·https·uni-app·iphone