uniapp自定义拖拽排列

uniapp自定义拖拽排列并改变下标

javascript 复制代码
<!-- 页面模板 -->
<template>
	<view class="container">
		<view v-for="(item, index) in list" :key="item.id" class="drag-item" :style="{
        transform: `translate(${activeIndex === index ? offsetX : 0}px, ${activeIndex === index ? offsetY : 0}px)`,
        transition: activeIndex === index ? 'none' : 'transform 0.3s',
        zIndex: activeIndex === index ? 999 : 1,
        boxShadow: activeIndex === index ? '0 8px 20px rgba(0,0,0,0.2)' : '0 2px 6px rgba(0,0,0,0.1)'
      }" @touchstart="handleTouchStart(index, $event)" @touchmove="handleTouchMove(index, $event)"
			@touchend="handleTouchEnd">
			{{ item.content }}
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				list: [
				{ id: 1, content: 'Item 1' },
				{ id: 2, content: 'Item 2' },
				{ id: 3, content: 'Item 3' },
				{ id: 4, content: 'Item 4' },
				{ id: 5, content: 'Item 5' },
				{ id: 6, content: 'Item 6' },
				{ id: 7, content: 'Item 7' },
				{ id: 8, content: 'Item 8' },
				{ id: 9, content: 'Item 9' },
				{ id: 10, content: 'Item 10' },
				{ id: 11, content: 'Item 11' },
				{ id: 12, content: 'Item 12' },
				{ id: 13, content: 'Item 13' },
				{ id: 14, content: 'Item 14' },
				], 
				activeIndex: -1, // 当前激活元素索引
				startX: 0, // 触摸起始X坐标
				startY: 0, // 触摸起始Y坐标
				offsetX: 0, // X轴偏移量
				offsetY: 0, // Y轴偏移量
				positions: [] // 元素位置缓存数组:ml-citation{ref="1,3" data="citationList"}
			}
		},
		mounted() {
			// this.initPositions()
		},
		methods: {
			// 初始化元素位置信息:ml-citation{ref="3,5" data="citationList"}
			initPositions() {
				uni.createSelectorQuery().in(this).selectAll('.drag-item')
					.boundingClientRect(rects => {
						this.positions = rects.map(rect => ({
							left: rect.left,
							top: rect.top,
							width: rect.width,
							height: rect.height
						}))
					}).exec()
			},

			// 触摸开始事件:ml-citation{ref="2,7" data="citationList"}
			handleTouchStart(index, e) {
				this.activeIndex = index
				this.startX = e.touches[0].clientX
				this.startY = e.touches[0].clientY
				this.initPositions()
			},

			// 触摸移动事件:ml-citation{ref="4,8" data="citationList"}
			handleTouchMove(index, e) {
				if (index !== this.activeIndex) return

				const currentX = e.touches[0].clientX
				const currentY = e.touches[0].clientY
				this.offsetX = currentX - this.startX
				this.offsetY = currentY - this.startY

				// 查找目标位置:ml-citation{ref="1,6" data="citationList"}
				const targetIndex = this.findTargetIndex(currentX, currentY)
				if (targetIndex !== -1 && targetIndex !== this.activeIndex) {
					this.swapElements(this.activeIndex, targetIndex)
					this.activeIndex = targetIndex
					this.startX = currentX
					this.startY = currentY
					this.offsetX = 0
					this.offsetY = 0
				}
			},

			// 查找目标插入位置:ml-citation{ref="5,6" data="citationList"}
			findTargetIndex(x, y) {
				for (let i = 0; i < this.positions.length; i++) {
					const pos = this.positions[i]
					if (x > pos.left && x < pos.left + pos.width &&
						y > pos.top && y < pos.top + pos.height) {
						return i
					}
				}
				return -1
			},

			// 交换数组元素:ml-citation{ref="2,7" data="citationList"}
			swapElements(oldIndex, newIndex) {
				const temp = [...this.list]
				const movedItem = temp.splice(oldIndex, 1)[0]
				temp.splice(newIndex, 0, movedItem)
				this.list = temp
				this.$nextTick(() => this.initPositions())
			},

			// 触摸结束事件:ml-citation{ref="4,8" data="citationList"}
			handleTouchEnd() {
				this.activeIndex = -1
				this.offsetX = 0
				this.offsetY = 0
			}
		}
	}
</script>

<style>
	.container {
		padding: 10px;
		overflow: hidden;
		/* 处理浮动元素换行 */
	}

	.drag-item {
		float: left;
		width: 160px;
		height: 80px;
		margin: 8px;
		background: #fff;
		border-radius: 12px;
		display: flex;
		align-items: center;
		justify-content: center;
		transition: all 0.3s;
		user-select: none;
	}
</style>
相关推荐
夜郎king13 分钟前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
辰风沐阳22 分钟前
JavaScript 的宏任务和微任务
javascript
夏幻灵1 小时前
HTML5里最常用的十大标签
前端·html·html5
冰暮流星1 小时前
javascript之二重循环练习
开发语言·javascript·数据库
Mr Xu_1 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js
未来龙皇小蓝2 小时前
RBAC前端架构-01:项目初始化
前端·架构
程序员agions2 小时前
2026年,微前端终于“死“了
前端·状态模式
万岳科技系统开发2 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
2501_915106322 小时前
app 上架过程,安装包准备、证书与描述文件管理、安装测试、上传
android·ios·小程序·https·uni-app·iphone·webview
程序员猫哥_2 小时前
HTML 生成网页工具推荐:从手写代码到 AI 自动生成网页的进化路径
前端·人工智能·html