uni-app简单实现一下拖拽排序

闲来无事,就想着写个拖拽排序的组件好了,虽然效果差了些,但以后我变强了,在优化嘛。🤪

示例:

创建组件(直接上代码):

<template>
	<view class="drag-and-drop-sort-A" :containerSize="[containerSize]">
		<template v-if="controlsPositionArray.length !== 0">
			<view v-for="(item, index) in controlsArray" :key="index" class="_item"
				:style="{'transition': (curretnControlsIndex === index ? 'initial' : '.3s'), 'z-index': (curretnControlsIndex === index ? 1 : 0), 'width': controlsSize.width + 'px', 'height': controlsSize.height + 'px', 'top': controlsPositionArray[index].top + 'px',  'left': controlsPositionArray[index].left + 'px'}">
				<view @touchstart="handleTouchstart($event, index)" @touchmove="handleTouchmove" @touchend="handleTouchend" :style="{'background': item}" style="width: 100%; height: 100%;">
					<slot name="content" :item="item"></slot>
				</view>
			</view>
		</template>
	</view>
</template>

<script>
	export default {
		name: "drag-and-drop-sort-A",
		props: {
			// 容器大小
			containerSize: {
				type: Object,
				default: () => ({ wdith: '100vw', height: '100vh' }),
			},
			// 控件的大小
			controlsSize: {
				type: Object,
				default: () => ({ width: 0, height: 0 }),
			},
			// 数据列表
			controlsList: {
				type: Array,
				default: () => [],
			},
		},
		data() {
			return {
				// 控件列表
				controlsArray: [],
				// 每行最大存放的个数
				maxWidthCount: 0,
				// 控件的间距
				margin: {
			
### 实现拖动排序功能 在uni-app实现拖动排序主要依赖于`touch`事件来处理列表项之间的交互。通过监听触摸开始(`touchstart`)、触摸移动(`touchmove`)以及触摸结束(`touchend`)三个阶段,可以精确控制元素位置的变化并完成排序操作[^4]。 对于希望简化开发过程的情况,可以选择集成现有的第三方库或者组件。例如,在某些场景下,开发者可能会考虑使用专门用于解决此类需求的插件或UI框架所提供的内置组件。然而针对具体的拖拽排序问题,并未直接提及特定名称的官方推荐插件;更多的是基于原生能力构建解决方案或是寻找社区贡献的相关资源。 下面是一个简单的示例代码片段,展示了如何利用上述提到的技术要点创建一个基本的可拖动排序列表: ```javascript // pages/sortList/sortList.vue <template> <view class="container"> <!-- 列表容器 --> <view v-for="(item, index) in items" :key="index" @touchstart="onTouchStart($event, item)" @touchmove="onTouchMove($event, item)" @touchend="onTouchEnd()" :style="{ transform: `translateY(${item.offset}px)` }" class="list-item">{{ item.text }}</view> </view> </template> <script> export default { data() { return { items: [ { text: 'Item 1', offset: 0 }, { text: 'Item 2', offset: 0 }, { text: 'Item 3', offset: 0 } ], activeIndex: null, startY: 0, startOffset: 0 }; }, methods: { onTouchStart(event, currentItem) { this.activeIndex = this.items.indexOf(currentItem); this.startY = event.touches[0].pageY; this.startOffset = currentItem.offset; }, onTouchMove(event, currentItem) { const moveY = event.touches[0].pageY - this.startY; let newIndex = Math.round((this.startOffset + moveY) / 80); // 假设每项高度为80px if (newIndex >= 0 && newIndex < this.items.length) { // 更新当前项的新索引及其偏移量 currentItem.offset = newIndex * 80; // 如果新旧索引不同,则交换两项的位置 if (newIndex !== this.activeIndex) { [this.items[this.activeIndex], this.items[newIndex]] = [this.items[newIndex], this.items[this.activeIndex]]; // 同步更新激活状态下的索引值 this.activeIndex = newIndex; } } }, onTouchEnd() { // 结束时重置所有项目的偏移量至零 setTimeout(() => { this.items.forEach(item => item.offset = 0); }, 300); this.activeIndex = null; } } }; </script> <style scoped> .container { padding-top: 20rpx; } .list-item { height: 80px; line-height: 80px; background-color: #f9f9f9; margin-bottom: 10rpx; border-radius: 5rpx; transition: all .3s ease-in-out; } </style> ``` 这段代码提供了一个基础版本的手指触控拖动排序逻辑,适用于大多数情况下的简单应用。当然实际项目里可能还需要考虑到更多细节优化用户体验,比如更复杂的动画效果或者其他业务规则上的约束条件等。
评论 35
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值