uni-app使用movable-area 实现数据的拖拽排序功能

文档地址

template部分
html 复制代码
<movable-area :style="getAreaStyle">
	<movable-view class="table-row" 
        v-for="v,i in move.list"
        :key="v.id"
        :y="v.y"
        @change="handle_moving"
		direction="vertical"
        @touchstart="handle_dragstart(i,v)" 
        @touchend="handle_dragend(i,v)"
		@longpress="handleLongpress(v)" 
        :disabled="move.disabled">
				<view class="table-cell">{{i+1}}</view>
				<view class="table-cell">选择物料</view>
	 </movable-view>
</movable-area>
css 复制代码
.table-cell,.table-row{
   height:50rpx;
}
.table-row{
  width:100%;
  display: flex;
}
.table-cell{
  width:200rpx;
}

注意使用movable-area时需要设置高度和宽度 否则默认10

js部分
javascript 复制代码
const move = reactive({
        list:[],
		disabled: true,
		activeIndex: -1,
		moveToIndex: -1,
		oldIndex: -1,
		tempDragInfo: {
			y: ''
		},
		cloneList: [],
		longpress: true,

	})

	// 获取位置
	const getPosition_y = (index) => {
		return index * 25
	}
	const getAreaStyle = computed(() => {
		return {
			width: '100%',
			height: move.list.length * 25 + 'px'
		}
	})

	// 初始化列表
	const initList = (list = []) => {
		const newList = JSON.parse(JSON.stringify(list));
		move.list = newList.map((item, index) => {
			return {
				...item,
				y: getPosition_y(index)
			}
		})
		move.cloneList = JSON.parse(JSON.stringify(move.list));
	}

	// 开始拖拽
	const handle_dragstart = (i,v) => {
		if(!v.id){
			return false;
		}
		move.activeIndex = i;
		move.oldIndex = i;
	}

	// 拖拽结束
	const handle_dragend = (i,v) => {
		if(!v.id){
			return false;
		}
		if (move.disabled) return;
		if (move.moveToIndex != -1 && move.activeIndex != -1 && move.activeIndex != move.moveToIndex) {
			move.cloneList.splice(move.moveToIndex, 0, ...move.cloneList.splice(move.activeIndex, 1));
		} else {
			move.list[move.activeIndex]['y'] = move.tempDragInfo.y;
		}
		initList(move.cloneList)
		move.activeIndex = -1;
		move.oldIndex = -1;
		move.moveToIndex = -1;
		move.disabled = true;
	}

	// 移动
	const handle_moving = (e) => {
		console.log({e})
		if (e.detail.source !== 'touch') return;
		let y = e.detail.y;
		move.tempDragInfo.y = y;
		const currentY = Math.floor((y + 12.5) / 25)
		move.moveToIndex = Math.min(currentY, move.list.length - 1);
		if (move.oldIndex != move.moveToIndex && move.oldIndex != -1 && move.moveToIndex != -1) {
			const newList = JSON.parse(JSON.stringify(move.cloneList));
			let splicItem = newList.splice(move.activeIndex, 1)[0]
			newList.splice(move.moveToIndex, 0, splicItem);
			move.list.forEach((item, index) => {
				if (index != move.activeIndex) {
					const itemIndex = newList.findIndex(val => val?.id === item?.id);
					item['y'] = getPosition_y(itemIndex);
				}
			});
			move.oldIndex = move.moveToIndex;
		}
	}


	const handleLongpress = (v) => {
		if(!v.id){
			return false
		}
		move.disabled = false;
	}
相关推荐
宸翰13 小时前
解决 uni-app App 端 vue-i18n 占位符丢失:封装跨端可用的 tf 格式化方法
前端·vue.js·uni-app
时光足迹1 天前
uni-app 视频通话实战:康复师与患者视频问诊的 6 个致命 Bug 与解决方案
android·ios·uni-app
时光足迹1 天前
腾讯云 TRTC UniApp SDK 从入门到上线
前端·vue.js·uni-app
时光足迹1 天前
uni-app 里把加密视频嵌入页面播放?我分析了 4 种方案,只有 1 种接近完美
前端·vue.js·uni-app
时光足迹1 天前
JPush UniApp UTS 插件完全参考手册:API、事件与厂商通道一网打尽
vue.js·ios·uni-app
时光足迹1 天前
极光推送全攻略(下):uni-app 代码实现与 iOS 排查实战
vue.js·ios·uni-app
时光足迹2 天前
极光推送全攻略(上):被iOS证书折磨了三天,我写了一份前端也能看懂的避坑指南
前端·ios·uni-app
spmcor3 天前
身份证读卡“无感登录”方案实践:从手动点击到自动检测
uni-app
PedroQue994 天前
uni-router v1.8.0新增冷启动守卫补执行
前端·uni-app
PedroQue995 天前
uni-router v1.7.0重磅更新:守卫重定向自由掌控
前端·uni-app