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>