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>
相关推荐
MY_TEUCK3 小时前
【AI 应用】前端接口联调工程化:把 Swagger 接入沉淀成可复用 Skill
前端·人工智能·uni-app·状态模式
上架ipa4 小时前
uniapp打包ios配置、申请证书、测试和上架综合教程
uni-app
00后程序员张4 小时前
完整指南 iOS App上架到App Store的步骤详解
macos·ios·小程序·uni-app·objective-c·cocoa·iphone
hhzz4 小时前
记录微信小程序tabbar不显示问题:uni-app Vue 3 自定义 tabBar 不渲染
vue.js·微信小程序·uni-app
存在的五月雨5 小时前
uniapp 一些组件的使用
java·前端·uni-app
久爱@勿忘5 小时前
uniappH5跳转小程序
前端·小程序·uni-app
郑州光合科技余经理15 小时前
同城O2O海外版二次开发实战:从支付网关到配送算法
开发语言·前端·后端·算法·架构·uni-app·php
启山智软1 天前
前沿主流技术栈商城系统(Java JDK21 + Vue3 + Uniapp)
java·开发语言·uni-app
WeirdOwl1 天前
uniapp 嵌入外部h5 报错/收不到消息
uni-app
敲代码的鱼哇3 天前
发送短信/拨打电话/获取联系人能力 UTS 插件(cz-sms)
android·前端·ios·uni-app·安卓·harmonyos·鸿蒙