vue拖拽删除实现

news2025/7/19 10:13:28

拖拽删除

背景

自营上传图片,但是需要排序和删除功能,所以用到了h5的拖拽
在这里插入图片描述
源元素: 即被拖拽的元素。

目标元素: 即合法的可释放元素。

每个事件的事件主体都是两者之一。

拖拽事件

在这里插入图片描述

触发顺序及次数

被拖拽元素,事件触发顺序是 dragstart->drag->dragend;对于目标元素,事件触发的顺序是 dragenter->dragover->drop/dropleave。

其中drag和dragover会分别在源元素和目标元素反复触发。整个流程一定是dragstart第一个触发,dragend最后一个触发。

这里还有一个注意的点,如果某个元素同时设置了dragover和drop的监听,那么必须阻止dragover的默认行为,否则drop将不会被触发。

  • 站在源元素和目标元素的角度来看,就是dragstart 可以获取到当前的信息,源dragenter可以获取到目标元素,dragend,此时拖拽结束,可以做碰撞检测的逻辑

移动位置

api使用

这里我利用 dragstart 记录源数据,和索引。利用dragenter记录目标元素的数据,和索引,等拖拽结束,利用dragend做位置移动逻辑。

排序逻辑

  • 利用splice, 先删除源数据,然后再目标元素之后,添加新元素。实现拖拽排序

比如将a 和b交换位置

  1. 获取a和b的索引
  2. 先将a删除
  3. 在b之后,再添加a
let oldData = 'a';
let newData = 'b';
let arr = ['d', 'a', 'c', 'b', 'e'];
let indexA = arr.indexOf(oldData); // 0
let indexB = arr.indexOf(newData); // 1
arr.splice(indexA, 1);
arr.splice(indexB, 0, oldData);
console.log('arr', arr); //[ 'd', 'c', 'b', 'a', 'e' ]

代码逻辑

<template>
	<div class="mg-top-wrap">
			<!-- @dragover="dragover($event)" -->
		<div
			class="drag-sort-box"
		>
			<div
				class="drag-sort-item"
				v-for="(item, index) in images"
				:key="item"
				:draggable="true"
				@dragstart="dragstart(item, index)"
				@dragenter="dragenter(item, $event)"
				@dragend="dragend(item, $event)"
				@dragover="dragover($event)"
				@mouseover="mouseover(index)"
				@mouseout="mouseout()"
			>
				<p
					:class="index === indexDel ? 'moxsind' : ''"
					@click="delPicHandler()"
				></p>

				<img :src="item.image_url" />
			</div>
		</div>
		<wd-button class="" @click="chooseImage()" :loading="loading">
			上传图片
			<input
				@change="uploadImg($event)"
				type="file"
				style="display: none"
				id="upload"
			/>
		</wd-button>
		<div>记得去图文详情保存哦~</div>
	</div>
</template>

<script setup>
import { onMounted, reactive, ref, watch } from 'vue';
import axios from '../../../utils/ajax';
import { WdMessage } from '@inagora/wd-view';
const props = defineProps({
	shopImage: Array,
});
const images = ref([]);

const emit = defineEmits(['change']);

watch(
	() => props.shopImage,
	(val) => {
		console.log('数据是否发生变化', val);
		if (val.length) {
			images.value = props.shopImage;
		}
	}
);

const itemClass = ref('');
// images.value = images.value.map((v, i) => (v = v + '?index=' + i)); //不重复key
console.log('sssss', images.value);
let oldData = null;
let newData = null;

const dragstart = (value, index) => {
	oldData = value;
	console.log('开始的值', images.value);
};
const dragenter = (value, e) => {
	newData = value;
	e.preventDefault();
};

const dragover = (e) => {
	e.preventDefault();
};
const indexDel = ref('');
const mouseover = (index) => {
	indexDel.value = index;
	console.log('index', index);
};
const mouseout = () => {
	indexDel.value = '';
};
const delPicHandler = () => {
	images.value.splice(indexDel.value, 1);
	// emit('change', images.value);
};

const dragend = () => {
	if (oldData !== newData) {
		let oldIndex = images.value.indexOf(oldData);
		let newIndex = images.value.indexOf(newData);

		let newItems = [...images.value];
		newItems.splice(oldIndex, 1);
		newItems.splice(newIndex, 0, oldData);
		images.value = [...newItems];
		console.log('结束的值', images.value);
		emit('change', images.value);
	}
};
const loading = ref(false);
const chooseImage = () => {
	document.getElementById('upload').click();
};
const uploadImg = (e) => {
	let file = e.target.files[0];
	let formdata = new FormData();
	formdata.append('file', file);
	uploadImage(formdata);
};
const uploadImage = (formdata) => {
	loading.value = true;
	axios.post('/Upload/uploadImage', formdata).then((res) => {
		if (!res.code) {
			loading.value = false;
			console.log('res.data', res.data);
			WdMessage({
				message: '上传成功',
				type: 'success',
			});
			images.value.push({ image: res.data.key, image_url: res.data.url });
			console.log('images.value', images.value);
			emit('change', images.value);

			// 刷新列表
		} else {
			loading.value = false;
			WdMessage({
				message: res.msg,
				type: 'error',
			});
		}
	});
};
</script>

<style lang="scss" scoped>
p {
	margin: 0;
	padding: 0;
}
.drag-sort-box {
	height: 330px;
	overflow: scroll;
	width: 100%;
	display: flex;
	flex-wrap: wrap;
}
.drag-sort-box .drag-sort-item {
	width: 200px;

	margin: 10px;
	cursor: pointer;
	transition: all 0.3s;
	// background: #ccc;
	position: relative;
}

.drag-sort-box .drag-sort-item img {
	width: 100%;
	transition: all 0.3s;
	position: relative;
}
.drag-sort-box .drag-sort-item .active {
	position: absolute;
	top: 0;
	left: 0;
	align-items: center;
	justify-content: center;
	background: url(https://jira.inagora.org/secure/projectavatar?pid=11206&avatarId=10326)
		no-repeat center center;
	width: 30px;
	height: 30px;
}

.moxsind {
	width: 100%;
	height: 100%;
	position: absolute;
	top: -10px;
	left: -10px;
	z-index: 10;
	background: url(https://s5.52ritao.cn/s/70/_620652.png) no-repeat;
	background-size: 18px 18px;
	width: 18px;
	height: 18px;
}
.mg-top-wrap {
	margin-top: 10px;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/35994.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

day5-day6【代码随想录】螺旋矩阵II

文章目录前言一、螺旋矩阵||&#xff08;力扣59&#xff09;二、螺旋矩阵&#xff08;力扣54&#xff09;前言 坚持循环不变量原则。 模拟顺时针画矩阵的过程: 填充上行从左到右 填充右列从上到下 填充下行从右到左 填充左列从下到上 由外向内一圈一圈这么画下去 一、螺旋矩阵…

大三保研夏令营须知及前期准备工作

前言 对于大三保研学生而言&#xff0c;学期将近结束&#xff1b;接踵而来的是接下来的保研准备。保研阶段通常可以分为&#xff1a;夏令营、预推免、九推(捡漏)。很多同学往往都是在前两个阶段就能获得满意的offer。 对于计算机专业来说&#xff0c;经历过2022年的“推免季”&…

项目实战——匹配系统(下)

目录 一、整体梳理 二、创建SpringCloud目录 三、创建子项目 四、实现接口 五、config网关配置 六、放行API 七、封装后端逻辑 八、对接匹配系统 九、修改数据库 十、实现匹配之后的逻辑 十一、线程锁 十二、匹配函数 上节课知识梳理&#xff1a; 用户浏览器打开之…

天津专升本报名时的报名点

2023年天津专升本报名区县及应届生、往届生报名点 天津市在校大三应届生报名点选自己的专科院校&#xff0c;往届生及在外省就读的应届生选户籍所在区招办。 退役士兵从天津入伍的选择学校作为报名点&#xff0c;外省市入伍的选择区招办。

slambook2(ch2)—— Ubuntu20.04 使用cmake + make自动化编译过程

slambook2&#xff08;ch2&#xff09;—— Ubuntu20.04 使用cmake make自动化编译过程主函数库函数libhello.cpplibhello.hCMakeLists.txt编译重新编译vim加行号主函数 main.cpp 库函数 libhello.cpp libhello.h CMakeLists.txt 编译 mkdir build && cd build c…

ASEMI肖特基二极管MBR30100CT特征,MBR30100CT应用

编辑-Z ASEMI肖特基二极管MBR30100CT参数&#xff1a; 型号&#xff1a;MBR30100CT 最大重复峰值反向电压&#xff08;VRRM&#xff09;&#xff1a;100V 最大平均正向整流输出电流&#xff08;IF&#xff09;&#xff1a;30A 峰值正向浪涌电流&#xff08;IFSM&#xff0…

通达信l1l2行情接口-十档行情有哪些优势?

据提供系统或用户编制的条件选股公式进行选股选定一个条件选股公式或多个组合条件后&#xff0c;计算机自动帮您选出当时或历史上某一段时间内满足条件的所有股票十档行情 英文&#xff0c;列在行情下载显示窗口&#xff0c;同时可保留成板块。 那通达信l1l2行情接口-十档行情…

map容器(20221125)

一、map/multimap容器 1、map基本概念 map中所有元素都是pair&#xff1b; pair第一个元素为key&#xff08;键值&#xff09;,起到索引的作用&#xff0c;第二个元素为value(实值)&#xff1b; 所有元素会根据元素的键值&#xff08;key&#xff09;自动排序。 map/multi…

论文阅读笔记 | 三维目标检测——PartA2算法

如有错误&#xff0c;恳请指出。 文章目录0. 前言与补充知识1. 背景2. 相关工作3. 网络结构3.1 Part-aware stageAnchor-free Proposal GenerationAnchor-based Proposal GenerationDiscussion Two Proposal Generation Strategies3.2 Part-aggregation stageROI-aware feature…

ORB-SLAM2 ---- Frame::ComputeBoW函数(TrackReferenceKeyFrame调用版)

目录 1.函数作用 2.什么是BowVec和FeatVec 3.代码 3.1 Frame::ComputeBoW解释 3.2 transform主函数&#xff1a;将一幅图像所有的特征点转化为BowVector和FeatureVector 3.3 transform&#xff1a;将描述子转化为Word id&#xff0c; Word weight&#xff0c;节点所属的…

[毕业设计]机器学习水域检测标注算法

前言 &#x1f4c5;大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科同学来说是充满挑战。为帮助大家顺利通过和节省时间与精力投…

uniapp里接入lottie-miniprogram详细指南

包工头&#xff1a;小张啊&#xff0c;我们页面里那几个gif也太low了&#xff0c;你能不能追求远大点。ui妹子&#xff1a;软件推荐可以用lottie实现。我&#xff1a;这玩意我耍过&#xff0c;交给我了。 牛逼已经吹出去了&#xff0c;开干&#xff0c; 遇到问题有&#xff0…

基于MxNet实现目标检测-YoloV3【附部分源码及模型】

文章目录前言目标检测发展史及意义一、数据集的准备1.标注工具的安装2.数据集的准备3.标注数据4.解释xml文件的内容二、网络结构的介绍三、代码实现0.工程目录结构如下1.导入库2.配置GPU/CPU环境3.数据加载器4.模型构建YoloV3-tinyYoloV35.模型训练1.学习率设置2.优化器设置3.损…

XSS绕过安全狗WAF

今天继续给大家介绍渗透测试相关知识&#xff0c;本文主要内容是XSS绕过安全狗WAF。 一、测试环境搭建 我们使用Vmware虚拟机搭建靶场环境。在Vmware虚拟机上&#xff0c;安装有PHPStudy&#xff0c;如下所示&#xff1a; 然后安装安全狗WAF&#xff0c;安全狗WAF有一系列的…

深度学习入门(五十二)计算机视觉——风格迁移

深度学习入门&#xff08;五十二&#xff09;计算机视觉——风格迁移前言计算机视觉——风格迁移课件样式迁移易于CNN的样式迁移教材1 方法2 阅读内容和风格图像3 预处理和后处理4 抽取图像特征5 定义损失函数5.1 内容损失5.2 风格损失5.3 全变分损失5.4 损失函数6 初始化合成图…

【瑞萨RA4M2】开发环境搭建和点灯指南

【瑞萨RA4系列开发板体验】开发环境搭建和新手点灯指南 文章目录【瑞萨RA4系列开发板体验】开发环境搭建和新手点灯指南一、简单开箱二、芯片简介三、开发环境搭建2.1 安装FSP(RASC)2.2 安装Keil MDK2.3 安装RA4M2 Keil Pack2.4 安装RFP(瑞萨烧录工具)三、新手点灯指南3.1 创建…

hoops编程指南:04.4用户交互突出显示

user interaction highlighting 1.突出显示 在执行选择之后&#xff0c;通常需要向用户提供关于所选内容的视觉反馈。例如&#xff0c;场景可能包含由多个几何体表示的飞机机翼的图片。然而&#xff0c;HOOPS Visualize对飞机机翼这一独特概念一无所知。因此&#xff0c;如果…

ES6 入门教程 28 异步遍历器 28.1 同步遍历器的问题 28.2 异步遍历的接口 28.3 for await...of

ES6 入门教程 ECMAScript 6 入门 作者&#xff1a;阮一峰 本文仅用于学习记录&#xff0c;不存在任何商业用途&#xff0c;如侵删 文章目录ES6 入门教程28 异步遍历器28.1 同步遍历器的问题28.2 异步遍历的接口28.3 for await...of28 异步遍历器 28.1 同步遍历器的问题 Itera…

【教学类-16-02】20221125《世界杯七巧板A4整页-随机参考图七巧板 3份一页》(大班)

效果展示&#xff1a; 单页效果 多页效果 预设样式&#xff1a; 背景需求&#xff1a; 2022年11月24日&#xff0c;大1班随机抽取的9位幼儿制作了9张拼图&#xff0c;发现以下三个问题&#xff1a; 1、粉红色辅助纸选择量多——9份作业有4位幼儿的七巧板人物是粉红色的 2、…

【计算机网络】以太网供电PoE - Power over Ethernet

.5BG? ?: J^ ~P YG: ~5PY^ 5&Y^ .#&J. 7&G7^. ~##?. :Y##PY?!~^:... .5#Y^ .7P&&&##BBBBB#B^ …