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

这篇具有很好参考价值的文章主要介绍了uni-app简单实现一下拖拽排序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

示例:

uniapp 拖拽,前端,小程序,javascript,vue

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

<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: {
					margin_x: 10,
					margin_y: 10,
				},
				// 记录所有控件的初始位置
				recordInitControlsPoisitonList: [],
				// 控件的数据
				controlsPositionArray: [],
				// 记录当前手指的位置
				recordPosition: {
					x: 0,
					y: 0,
				},
				// 记录当前操作的控件数据
				recordControlsPositionItem: {},
				// 当前操作的控件的下标
				curretnControlsIndex: -1,
				// 是否在移动中
				isMobile: false,
			};
		},
		mounted() {
			// 获取系统信息
			this.systemInfo = uni.getSystemInfoSync();
			// 获取控件列表
			this.controlsArray = this.controlsList;
			
			// 初始化控件的位置
			this.controlsPositionArray = this.initControlsPosition();
		},
		methods: {
			/** 初始化各个控件的位置 */
			initControlsPosition() {
				// 用于返回出去的新数组
				let tempArray = [];
				// 每行最大存放的个数
				this.maxWidthCount = parseInt(this.systemInfo.windowWidth / (this.controlsSize.width + this.margin.margin_x));

				// 设置控件位置 - 这边多记录一个位置 之后会用到
				for(let i = 0, j = 0, k = 0; i < this.controlsList.length + 1; i++) {
					tempArray[i] = {
						left: j * (this.controlsSize.width + this.margin.margin_x) + this.margin.margin_x,
						top: k * (this.controlsSize.height + this.margin.margin_y) + this.margin.margin_y,
					}
					k = j + 1 === this.maxWidthCount ? ++k : k;
					j = j + 1 === this.maxWidthCount ? 0 : ++j;
				}
				
				// 记录数据 - 进行深拷贝
				this.recordInitControlsPoisitonList = [...tempArray];
				// 返回数据
				return tempArray;
			},
			
			/** 处理手指触摸后移动 */
			handleTouchmove(event) {
				const { pageX, pageY } = event.touches[0];
				
				// 获取移动的差
				this.$set(this.controlsPositionArray, this.curretnControlsIndex, {
					left: this.controlsPositionArray[this.curretnControlsIndex].left + (pageX - this.recordPosition.x),
					top: this.controlsPositionArray[this.curretnControlsIndex].top + (pageY - this.recordPosition.y),
				});
				// 记录位置
				this.recordPosition = { x: pageX, y: pageY };
				// 判断当前移动的位置是否需要进行排序
				// 向右移动
				if(this.curretnControlsIndex + 1 !== this.controlsList.length && (this.curretnControlsIndex + 1) % this.maxWidthCount !== 0 && this.controlsPositionArray[this.curretnControlsIndex].left + this.controlsSize.width >= this.recordInitControlsPoisitonList[this.curretnControlsIndex].left + this.controlsSize.width + this.margin.margin_x + this.controlsSize.width / 2) {
					this._handleChangeControlsPosition(this.curretnControlsIndex + 1);
				}
				// 向左移动
				else if(this.curretnControlsIndex % this.maxWidthCount !== 0 && this.controlsPositionArray[this.curretnControlsIndex].left <= this.recordInitControlsPoisitonList[this.curretnControlsIndex - 1].left + this.controlsSize.width / 2 && this.controlsPositionArray[this.curretnControlsIndex].top < this.recordInitControlsPoisitonList[this.curretnControlsIndex].top + this.controlsSize.height / 3 + this.margin.margin_y && this.controlsPositionArray[this.curretnControlsIndex].top > this.recordInitControlsPoisitonList[this.curretnControlsIndex].top - this.controlsSize.height / 3 - this.margin.margin_y) {
					this._handleChangeControlsPosition(this.curretnControlsIndex - 1);
				}
				// 向下拖动
				else if(Math.ceil(this.curretnControlsIndex / this.maxWidthCount) !== Math.ceil(this.controlsList.length / this.maxWidthCount) && this.controlsPositionArray[this.curretnControlsIndex].top + this.controlsSize.height > this.recordInitControlsPoisitonList[this.curretnControlsIndex].top + this.controlsSize.height + this.margin.margin_y + this.controlsSize.height / 2) {
					this._handleChangeControlsPosition((this.curretnControlsIndex + this.maxWidthCount) >= this.controlsArray.length ? this.controlsArray.length - 1 : this.curretnControlsIndex + this.maxWidthCount);
				}
				// 向上拖动
				else if(parseInt(this.curretnControlsIndex / this.maxWidthCount) !== 0 && this.controlsPositionArray[this.curretnControlsIndex].top < this.recordInitControlsPoisitonList[this.curretnControlsIndex].top - this.margin.margin_y - this.controlsSize.height / 3 * 2) {
					this._handleChangeControlsPosition(this.curretnControlsIndex - this.maxWidthCount);
				}
			},
			
			/** 处理手指触摸开始事件 */
			handleTouchstart(event, index) {
				const { pageX, pageY } = event.touches[0];
				
				// 记录一些数据
				this.curretnControlsIndex = index;
				this.recordPosition = { x: pageX, y: pageY };
				this.recordControlsPositionItem = this.controlsPositionArray[index];
			},
		
			/** 处理手指松开事件 */
			handleTouchend(event) {
				// 将操控的控件归位
				this.controlsPositionArray[this.curretnControlsIndex] = this.recordInitControlsPoisitonList[this.curretnControlsIndex];
				this.curretnControlsIndex = -1;
			},
			
			/**
			 * 处理交换控件位置的方法 - 
			 * @param {number} index	需要与第几个下标交换位置
			 * */
			_handleChangeControlsPosition(index) {
				// 判断是否在交换中
				if(this.isMobile) {
					return;
				}
				this.isMobile = true;
				
				// 记录当前操控的控件数据
				let tempControls = this.controlsArray[this.curretnControlsIndex];
				// 交换位置
				this.controlsArray[this.curretnControlsIndex] = this.controlsArray[index];
				this.controlsArray[index] = tempControls;
				
				// 调整控件位置数据
				this.controlsPositionArray[index] = this.controlsPositionArray[this.curretnControlsIndex];
				this.controlsPositionArray[this.curretnControlsIndex] = this.recordControlsPositionItem;
				
				// 改变当前选中的位置
				this.curretnControlsIndex = index;
				
				// 记录新位置的数据
				this.recordControlsPositionItem = this.recordInitControlsPoisitonList[this.curretnControlsIndex];
				
				// 交换结束
				this.isMobile = false;
			},
		}
	}
</script>

<style scoped lang="scss">
	.drag-and-drop-sort-A {
		position: relative;
		
		._item {
			position: absolute;
		}
	}
</style>

引入组件:

在之前的基础上优化了下,使用插槽自定义内容文章来源地址https://www.toymoban.com/news/detail-520493.html

<template>
	<view>
		<!-- controlsList 表示控件的列表  controlsSize 表示每个控件的大小 -->
		<drag-and-drop-sort :controlsList="dataArray" :controlsSize="{width: 50, height: 50}">
			<!-- 自定义内容 -->
			<template #content="{item}">
				<view :style="{'background': item.color}" style="display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">
					{{item.label}}
				</view>
			</template>
		</drag-and-drop-sort>
	</view>
</template>

<script>
import dragAndDropSort from '@/components/drag-and-drop-sort-A/drag-and-drop-sort-A.vue';
export default {
	components: {
		dragAndDropSort,
	},
	data() {
	    return {
	        // 这个内容可以自定义
			dataArray: [
				{color: '#ee3131', label: '1'},
				{color: '#2dc3d5', label: '2'},
				{color: '#f5aa41', label: '3'},
				{color: '#42b983', label: '4'},
				{color: '#1983fb', label: '5'},
				{color: '#a15afd', label: '6'},
				{color: '#ffe874', label: '7'},
				{color: '#00a8fb', label: '8'},
				{color: '#f36586', label: '9'},
				{color: '#16d46b', label: '10'},
			],
		}
	},
};
</script>

到了这里,关于uni-app简单实现一下拖拽排序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【UniApp】-uni-app-打包成网页

    经过上一篇文章的介绍,已经将这个计算器的计算功能实现了,接下来就是我们项目当中的一个发包上线阶段,我模拟一下,目的就是为了给大家介绍一下,uni-app是如何打包成网页的。 除了可以打包成网页,uni-app还可以打包成小程序、App、H5、快应用等等,后面在单独开文

    2024年02月04日
    浏览(72)
  • Uniapp uni-app学习与快速上手

    个人开源uni-app开源项目地址:准备中 在线展示项目地址:准备中 什么是uni-app uni,读 you ni ,是统一的意思。 Dcloud即数字天堂(北京)网络技术有限公司是W3C成员及HTML5中国产业联盟发起单位,致力于推进HTML5发展构建,HTML5生态。 2012年,DCloud开始研发小程序技术,优化webvie

    2024年02月09日
    浏览(64)
  • 【uni-app】UniApp实现微信小程序中拨打手机电话和长按加微信客服好友(完整代码示例)

    UniApp实现微信小程序中拨打手机电话和长按加微信客服好友(完整代码示例)

    2024年02月11日
    浏览(69)
  • uni-app做A-Z排序通讯录、索引列表

    上图是效果图,三个问题 访问电话通讯录,拿数据 拿到用户的联系人数组对象,之后根据A-Z排序 根据字母索引快速搜索 首先说数据怎么拿 - 社区有指导 https://ask.dcloud.net.cn/question/64117 uniapp 调取通讯录 这样就实现了第一步,接下来分析拿到的数据,做处理。 从这部分数据看

    2024年01月22日
    浏览(34)
  • 【uni-app教程】四、UniAPP 路由配置及页面跳转

    uni-app 页面路由为框架统一管理,开发者需要在pages.json里配置每个路由页面的路径及页面样式。类似小程序在 app.json 中配置页面路由一样。所以 uni-app 的路由用法与 Vue Router 不同,如仍希望采用 Vue Router 方式管理路由,可在插件市场搜索 Vue-Router。 uni-app 有两种页面路由跳转

    2024年01月16日
    浏览(77)
  • 【UniApp】-uni-app-项目实战页面布局(苹果计算器)

    经过前面的文章介绍,基本上 UniApp 的内容就介绍完毕了 那么从本文开始,我们就开始进行一个项目的实战 这次做的项目是苹果计算器,这个项目的难度不是很大,但是也不是很简单,适合练手 打开 HBuilderX,点击左上角 文件 - 新建 - 项目 : 项目创建完毕之后,首先来分析

    2024年02月04日
    浏览(67)
  • 在 WebStorm 中开发 uni-app - 用vue2实现手机APP(apk) + 微信小程序项目开发方案 webstorm开发的uniapp + hbuilderx进行app 小程序打包

    我们主要分析了如下小程序开发框架,主要包括: 框架 技术栈 案例 微信小程序 支付宝小程序 百度小程序 头条小程序 H5 App uni-app Vue 丰富 ⭕ ⭕️ ⭕️ ⭕ ⭕️ ⭕ Taro React 丰富 ⭕ ⭕ ⭕ ⭕ ⭕ ⭕ wepy Vue 丰富 ⭕ ❌ ❌ ❌ ❌ ❌ mpvue Vue 丰富 ⭕ ❌ ❌ ❌ ⭕️ ❌  首先,就要排

    2024年02月05日
    浏览(97)
  • 在 WebStorm 中开发 uni-app - 用vue2实现手机APP(apk) + 微信小程序项目开发方案 webstorm开发的uniapp + hbuilderx进行app 小程序打包

    我们主要分析了如下小程序开发框架,主要包括: 框架 技术栈 案例 微信小程序 支付宝小程序 百度小程序 头条小程序 H5 App uni-app Vue 丰富 ⭕ ⭕️ ⭕️ ⭕ ⭕️ ⭕ Taro React 丰富 ⭕ ⭕ ⭕ ⭕ ⭕ ⭕ wepy Vue 丰富 ⭕ ❌ ❌ ❌ ❌ ❌ mpvue Vue 丰富 ⭕ ❌ ❌ ❌ ⭕️ ❌  首先,就要排

    2023年04月15日
    浏览(81)
  • WebStorm开发uni-app ,用vue2实现手机APP(apk) + 微信小程序多端项目开发方案 webstorm开发的uniapp + hbuilderx进行app 小程序打包

    我们主要分析了如下小程序开发框架,主要包括: 框架 技术栈 案例 微信小程序 支付宝小程序 百度小程序 头条小程序 H5 App uni-app Vue 丰富 ⭕ ⭕️ ⭕️ ⭕ ⭕️ ⭕ Taro React 丰富 ⭕ ⭕ ⭕ ⭕ ⭕ ⭕ wepy Vue 丰富 ⭕ ❌ ❌ ❌ ❌ ❌ mpvue Vue 丰富 ⭕ ❌ ❌ ❌ ⭕️ ❌  首先,就要排

    2024年02月11日
    浏览(75)
  • #Uniapp:uni-app中vue2生命周期--11个

    uni-app中vue2生命周期 生命周期钩子 描述 H5 App端 小程序 说明 beforeCreate 在实例初始化之后被调用 详情 √ √ √ created 在实例创建完成后被立即调用 详情 √ √ √ beforeMount 在挂载开始之前被调用 详情 √ √ √ mounted 挂载到实例上去之后调用 详情 注意:此处并不能确定子组件

    2024年02月02日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包