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>
相关推荐
小小怪下士_---_1 分钟前
uniapp开发微信小程序自定义导航栏
前端·vue.js·微信小程序·小程序·uni-app
anyup3 小时前
🔥🔥 uView Pro:Vue3+TS重构的uni-app开源组件库,文档免费无广告!
前端·vue.js·uni-app
样子201814 小时前
Uniapp 之renderjs解决swiper+多个video卡顿问题
前端·javascript·css·uni-app·html
fakaifa16 小时前
点大餐饮独立版系统源码v1.0.3+uniapp前端+搭建教程
小程序·uni-app·php·源码下载·点大餐饮·扫码点单
Bug改不动了18 小时前
React Native 与 UniApp 对比
react native·react.js·uni-app
anyup21 小时前
🔥🔥 10 天 Star 破百!uView Pro 文档也开源啦:完全免费、无广告、高效上手
前端·vue.js·uni-app
fakaifa1 天前
【最新版】CRMEB Pro版v3.4系统源码全开源+PC端+uniapp前端+搭建教程
人工智能·小程序·uni-app·php·crmeb·源码下载·crmebpro
2501_915918412 天前
iOS 应用上架全流程实践,从开发内测到正式发布的多工具组合方案
android·ios·小程序·https·uni-app·iphone·webview
梦里寻码2 天前
自行食用 uniapp 多端 手写签名组件
前端·uni-app
不如摸鱼去3 天前
Trae 辅助下的 uni-app 跨端小程序工程化开发实践分享
微信小程序·小程序·uni-app·aigc·ai编程