vue拖拽删除实现

news/2024/5/3 18:38:28/文章来源:https://blog.csdn.net/qq_38845858/article/details/128037135

拖拽删除

背景

自营上传图片,但是需要排序和删除功能,所以用到了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)" --><divclass="drag-sort-box"><divclass="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.luyixian.cn/news_show_225480.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构学习笔记(Ⅳ):串

目录 1 串 1.1 定义与基本操作 1.定义 2.基本操作 1.2 串的存储结构 1.顺序存储 2.链式存储 3.基于顺序存储实现基本操作 2 串的朴素模式匹配算法 2.1 朴素模式匹配算法 2.2 KMP算法 1.优化思路 2.计算next数组 2.3 KMP算法优化 1 串 1.1 定义与基本操作 1.定义…

机器学习笔记之高斯网络(二)高斯贝叶斯网络

机器学习笔记之高斯网络——高斯贝叶斯网络引言回顾高斯网络贝叶斯网络&#xff1a;因子分解高斯贝叶斯网络&#xff1a;因子分解引言 上一节介绍了高斯网络及其条件独立性&#xff0c;本节将介绍高斯贝叶斯网络。 回顾 高斯网络 高斯网络最核心的特点是&#xff1a;随机变…

【软件测试】作为测试人,因工作与开发吵了一架碰撞,该咋办......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 测试与开发在工作中…

Redis数据库redisDb源码分析

写在前面 以下内容是基于Redis 6.2.6 版本整理总结 一、组织方式 Redis服务器将所有的数据库 都保存在src/server.h/redisServer结构中的db数组中。db数组的每个entry都是src/server.h/redisDb结构&#xff0c;每个redisDb结构代表一个数据库。Redis默认有16个数据库。 1.1…

Android App开发音量调节中实现拖动条和滑动条和音频管理器AudioManager讲解及实战(超详细 附源码和演示视频)

需要源码请点赞关注收藏后评论区留下QQ~~~ 一、拖动条和滑动条 拖动条SeekBar继承自进度条ProgressBar&#xff0c;它与进度条的不同之处在于&#xff0c;进度条只能在代码中修改进度值&#xff0c;不能由用户改变进度值&#xff0c;拖动条不仅可以在代码中修改进度值&#xf…

Greenplum数据库故障排查及修复

场景一&#xff1a;gp服务正常&#xff0c;存在部分segment实例丢失 1、异常现象 主节点切换gpadmin用户输入gpstate查看状态 如果红色框内有指向左边的箭头则说明存在部分segment实例丢失。 2、排查思路 首先查看主节点日志&#xff0c;重点关注发生segment丢失那段时间的…

Kafka开发环境搭建

kafka开发环境搭建一、安装Java环境1.1、下载Linux下的安装包1.2、解压缩安装包1.3、解压后的文件移到/usr/lib目录下1.4、配置java环境变量二、 Kafka的安装部署2.1、下载安装Kafka2.2、配置和启动zookeeper2.3、启动和停止Kafka后言一、安装Java环境 1.1、下载Linux下的安装…

【web前端开发】HTML知识点超详细总结

文章目录什么是网页常用的浏览器及内核VScode和WebStrom使用HTML常用标签文档类型<!DOCTYPE>网页语言lang字符集title标签标题标签段落和换行标签文本格式化标签div和span标签图像标签路径相对路径同一级路径上一级路径:下一级路径绝对路径链接标签超链接标签外部链接:内…

(DS90UB3702TRURRQ1) LT8640SHV-2低噪声降压稳压器QFN

LT8640/LT8640-1降压稳压器采用Silent Switcher架构&#xff0c;设计用于最大限度地降低EMI/EMC辐射并在高达3MHz的频率下提供高效率。由于具有2.5μA的超低静态电流&#xff08;当输出处于全面调节状态时&#xff09;&#xff0c;因此适用于要求在非常小负载电流条件下获得极高…

【Linux】(五)GateWay远程开发方式-实验室服务器使用GateWay远程开发

Jetbrains GateWay 方式系列文章一、服务器情况简介1.1服务器及用户1.2 cuda1.3 conda环境二、Jetbrains GateWay方式连接2.1 下载2.2 配置2.3 连接管理及附加说明2.3.1 关闭或退出2.3.2 重连附录公共数据集系列文章 &#xff08;一&#xff09;服务器初次配置及安装vncserver…

【CVPR 2022】QueryDet:加速高分辨率小目标检测

大连不负众望&#xff0c;疫情了&#xff0c;我们又封校了&#xff0c;可能初步封个5678天&#xff0c;微笑jpg 论文地址&#xff1a;https://arxiv.org/pdf/2103.09136.pdf 项目地址&#xff1a;https://github.com/ ChenhongyiYang/QueryDet-PyTorch 1. 简介 背景&#xf…

基于Netty的高性能RPC框架(分布式缓存、雪花算法、幂等性)

文章目录前言介绍1. 服务提供2. 安全策略3. 设计模式亮点1. 信息摘要算法的应用2. 心跳机制3. SPI 机制4. IO 异步非阻塞5. RNF 协议快速开始1.依赖1.1 直接引入1.2 maven引入2. 启动 Nacos3. 提供接口4. 启动服务5. 启动客户端5. 额外配置5.1 配置文件5.2 日志配置6. 场景应用…

电脑录屏快捷键是什么?win10自带屏幕录制在哪

​在使用电脑的过程中&#xff0c;我们难免会遇到使用电脑录屏功能。有时候可能是想录制网课&#xff0c;有时候可能是想录制游戏的精彩操作&#xff0c;有时候可能只是想录制会议内容。 电脑录屏能够将重要的画面内容进行录制&#xff0c;十分的方便。但也有很多的小伙伴不清…

傻白入门芯片设计,IP, MCM, SiP, SoC 和 Chiplet的区别(二)

一、IP&#xff1a; 早期的复制电路都是全定制&#xff0c;比如Intel的4004cpu&#xff0c;这种设计非常耗时。考虑到cpu的很多模块有相似的地方&#xff0c;能不能把这些东西模块化&#xff1f;于是就有了IP核的概念&#xff0c;Intelligent Property&#xff0c;即知识产权核…

EPICS -- asynRecord记录使用示例

这个示例演示了如何使用asynRecord记录 1、硬件准备工作 在这里准备了一个型号为NPort 5650-8-DT的Moxa串口服务器&#xff0c;用于一根交叉DB9双母头线缆连接设备上端口2和端口3&#xff0c;使之可以相互通信。 串口服务器配置如下&#xff1a; IP地址&#xff1a;192.168…

【Spring(五)】引入篇:一文带你弄懂AOP的底层原理(动态代理)

有关Spring的所有文章都收录于我的专栏&#xff1a;&#x1f449;Spring&#x1f448; 目录 一、前言 二、使用AOP需要的依赖 三、引入 四、AOP的底层原理之动态代理 五、总结 相关文章 【Spring&#xff08;一&#xff09;】如何获取对象&#xff08;Bean&#xff09;【Sprin…

移远EC20 4G模块LTE开发板三网通模块 MQTT阿里云物联网STM32代码

usb转tdl ath 挂断 22点评&#xff0c;要接转送帽 ATQGPSLOC? gps定位 ATQGPS1通过命令启动 启动好之后 505还没有启动 516 还没有定位好&#xff0c; 新版本数据模块&#xff0c;带电瓶转换芯片 效果会更好一些&#xff0c;专用的di芯片&#xff0c;单独把他tdl 1.8v转换…

JS if else语句详解

在正常情况下&#xff0c;JavaScript 脚本是按顺序从上到下执行的&#xff0c;这种结构被称为顺序结构。如果使用 if、else/if 或 switch 语句&#xff0c;可以改变这种流程顺序&#xff0c;让代码根据条件选择执行的方向&#xff0c;这种结构被称为分支结构。 if语句 if 语句…

分布式计算模型Mapreduce实践与原理剖析(二)

第二章 MapReduce核心组件实战 2.1 MapReduce中分区组件 需求&#xff1a;根据单词的长度给单词出现的次数的结果存储到不同文件中&#xff0c;以便于在快速查询 思路&#xff1a; 1、定义Mapper逻辑 2、定义Reducer逻辑 3、自定义分区Partitioner这个案例主要的逻辑在这个…

[附源码]SSM计算机毕业设计旅游管理系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…