【sgDragUploadFolder】自定义组件:自定义拖拽文件夹上传组件,支持上传单个或多个文件/文件夹,右下角上传托盘出现(后续更新...)

特性:

  1. 支持在拖拽上传单个文件、多个文件、单个文件夹、多个文件夹
  2. 可自定义headers
  3. 可自定义过滤上传格式
  4. 可自定义上传API接口
  5. 支持显示/隐藏右下角上传队列托盘

sgDragUploadFolder源码

<template><div :class="$options.name" :dragenter="isDragenter"><!-- 上传按钮_________________________________________________________ --><!-- 上传文件 --><el-uploadref="uploadFile":show-file-list="false":headers="headers":accept="accept.toString()":action="actionUrl":data="actionData":before-upload="beforeUpload":on-success="uploadSuccess":on-error="uploadError"multiple:name="name":auto-upload="autoUpload"></el-upload><!-- 上传文件夹 --><el-uploadref="uploadFolder":show-file-list="false":headers="headers":action="actionUrl":data="actionData":before-upload="beforeUpload":on-success="uploadSuccess":on-error="uploadError":on-exceed="exceed"multiple:drag="(drag === '' || drag) && !__checkDisabledDrag()":name="name":auto-upload="autoUpload"></el-upload><!-- _________________________________________________________ --><!-- 上传托盘(右下角) --><sgUploadTrayv-model="showUploadTray":data="uploadList"@stopUpload="stopUpload"@dragStart="$emit(`dragUploadTrayStart`, true)"@dragEnd="$emit(`dragUploadTrayEnd`, true)"v-if="!(hideUploadTray === '' || hideUploadTray) && !sgUploadTray"resizeable/></div></template><script>import sgUploadTray from "@/vue/components/admin/sgUploadTray";export default {name: "sgDragUploadFolder",components: { sgUploadTray },data() {return {// 上传----------------------------------------name: "file", //上传的文件字段名headers: { kkToken: localStorage.token }, //获取token(注意仔细看后端接受token的字段名是不是叫做“token”)accept: `.${["png", "jpg", "jpeg", "bmp", "gif", "svg"].join(",.")}`, //默认只支持图片格式上传// actionUrl: `${this.$d.API_ROOT_URL}/customer/importCustomerData`,actionUrl: `#`,actionData: {},dur: 100,percent: 100,uploadList: [],showUploadTray: false,uploadFileBtn: null, //上传文件uploadFolderBtn: null, //上传文件夹isDragenter: false, //是否拖入leaveEvents: ["mouseenter","mouseover","mousemove","mouseout","blur","visibilitychange",],dragAreaDom: null, //拖拽放入区域isDragTrigger: false, //是否为拖拽触发上传maxSize: null, //支持最大上传文件大小autoUpload: true, //是否在选取文件后立即进行上传// ----------------------------------------};},props: ["data", //上传可选参数"hideUploadTray", //不显示上传托盘"hideUploadTrayWhenDrag", //拖拽上传的时候隐藏上传托盘(默认显示)"drag", //是否支持拖拽文件、文件夹或多个文件"disabledWhenShowSels", //当出现对应['sel','sel','sel',...]的时候,屏蔽拖拽上传(譬如出现element的v-modal)"sgUploadTray", //引用外部公共托盘组件dom(这种方式主要是为了解决同一个页面有多个上传托盘组件导致冲突的问题)],watch: {data: {handler(d) {if (d) {d.name && (this.name = d.name);d.headers && (this.headers = d.headers);d.accept && (this.accept = d.accept);d.actionUrl && (this.actionUrl = d.actionUrl);d.actionData && (this.actionData = d.actionData);d.maxSize && (this.maxSize = d.maxSize);typeof d.autoUpload !== "undefined" && (this.autoUpload = d.autoUpload);}},deep: true,immediate: true,},drag: {handler(d) {if (d === "" || d) {this.addEvents();} else {this.removeEvents();}},deep: true,immediate: true,},showUploadTray(newValue, oldValue) {this.sgUploadTray && (this.sgUploadTray.show = newValue);},uploadList: {handler(d) {if (this.sgUploadTray) {this.sgUploadTray.uploadList || (this.sgUploadTray.uploadList = []);let uploadList = this.sgUploadTray.uploadList;d.forEach((newVal) => {// 避免重复添加到上传列表if (!uploadList.some((oldVal) => oldVal.uid == newVal.uid)) {uploadList.push(newVal);if (this.hideUploadTrayWhenDrag === "" || this.hideUploadTrayWhenDrag) {this.sgUploadTray.show = false; //不显示右下角上传托盘} else {this.sgUploadTray.show = true; //显示右下角上传托盘}}});}},deep: true,// immediate: true,},},mounted() {this.$nextTick(() => {this.uploadFileBtn = this.$refs.uploadFile.$children[0].$refs.input;this.uploadFolderBtn = this.$refs.uploadFolder.$children[0].$refs.input;this.uploadFolderBtn && (this.uploadFolderBtn.webkitdirectory = true); //让el-upload支持上传文件夹this.dragAreaDom = this.$refs.uploadFolder.$el.querySelector(`.el-upload-dragger`);this.dragAreaDom && this.dragAreaDom.addEventListener("drop", this.drop);});},destroyed() {this.removeEvents();},methods: {__checkDisabledDrag(d) {let aa = this.disabledWhenShowSels || [];aa && (Array.isArray(aa) || (aa = [aa]));let r = [];for (let i = 0, len = aa.length; i < len; i++) {let a = aa[i];let dom = document.querySelector(a);if (dom) {r.push(dom);return true;}}return r.length !== 0;},// 监听----------------------------------------addEvents(d) {this.removeEvents();addEventListener("dragenter", this.dragenter);this.leaveEvents.forEach((v) => addEventListener(v, this.leave));this.dragAreaDom && this.dragAreaDom.addEventListener("drop", this.drop);},removeEvents(d) {removeEventListener("dragenter", this.dragenter);this.leaveEvents.forEach((v) => removeEventListener(v, this.leave));this.dragAreaDom && this.dragAreaDom.removeEventListener("drop", this.drop);},dragenter(d) {this.isDragTrigger = true;this.isDragenter = true;},leave(d) {this.isDragenter = false;},drop(d) {// 触发拖拽上传this.uploadDragFiles(d,(file) => {file.isDragFile = true;this.beforeUpload(file);},(files) => {});},// 循环获取拖拽过来的file----------------------------------------uploadDragFiles(e, uploadFunc, completeFunc) {let files = [],items = [].slice.call(e.dataTransfer.items);items.forEach((v, i) => {const webkitGetAsEntry = v.webkitGetAsEntry();eval(webkitGetAsEntry.isDirectory ? "setfolder" : "setfile")(webkitGetAsEntry);});// 处理文件夹function setfolder(webkitGetAsEntry) {webkitGetAsEntry.createReader().readEntries((entries) =>entries.forEach((item) => (item.isFile ? setfile(item) : setfolder(item))));}// 处理文件function setfile(webkitGetAsEntry) {webkitGetAsEntry.file((file) => {uploadFunc && uploadFunc(file);files.push(file);});}completeFunc && completeFunc(files);},// 上传按钮触发----------------------------------------triggerUploadFile(d) {this.isDragTrigger = false;this.uploadFileBtn && this.uploadFileBtn.click();},triggerUploadFolder(d) {this.isDragTrigger = false;this.uploadFolderBtn && this.uploadFolderBtn.click();},// 判断是否相同uidsame_uid_lastModified(uid, file) {return (uid == file.uid ||uid == file.lastModified ||uid == (file.raw || {}).lastModified);},// 获取uidget_uid(file) {return file.uid || file.lastModified || (file.raw || {}).lastModified;},// 上传文件----------------------------------------------------------------showFakeLoading(file) {this.$emit(`showFakeLoading`, file);file.raw && (file = file.raw);file = this.uploadList.find((v) => this.same_uid_lastModified(v.uid, file)); //拖拽上传的时候没有uidclearInterval(file.interval);file.percent = 0;file.interval = setInterval(() => {file.percent >= 99 ? this.hideFakeLoading(file) : file.percent++;}, this.dur);},hideFakeLoading(file, { type, tip, color } = {}) {this.$emit(`hideFakeLoading`, file);// file.raw && (file = file.raw);//不需要2023.12.18file = this.uploadList.find((v) => this.same_uid_lastModified(v.uid, file)); //拖拽上传的时候没有uidclearInterval(file.interval);switch (type) {case "error":file.percent = 0;break;case "success":default:file.percent = 100;}type && (file.type = type);tip && (file.tip = tip);color && (file.color = color);},exceed(file, fileList) {this.$message.error("上传文件数量太大,分散上传吧!");},stopUpload(d) {this.$refs.uploadFolder.abort();},//文件上传之前beforeUpload(file) {if ((this.drag === "" || this.drag) && this.isDragTrigger) {if (!file.isDragFile) return; //拖拽模式下,如果不是原生js捕获到的拖拽文件,就不进入上传队列(区别开两个el-upload组件避免重复上传)}this.uploadList.unshift({interval: null,uid: this.get_uid(file), //拖拽上传的时候没有uidpercent: 0, //加载进度name: file.name,size: file.size,type: file.type,webkitRelativePath: file.webkitRelativePath,type: "",tip: "",color: "",});if (this.hideUploadTrayWhenDrag === "" || this.hideUploadTrayWhenDrag) {this.showUploadTray = false; //不显示右下角上传托盘} else {this.showUploadTray = true; //显示右下角上传托盘}// 判断是不是特定的格式________________________let isFile =this.accept === "*"? true: this.accept.includes(file.name.toLocaleLowerCase().split(".").pop());const minSize = 0.001; //限制文件最小1KBconst isAllowMinSize = file.size / 1024 / 1024 > minSize;isAllowMinSize ||this.$message.error("上传文件大小不能小于" + minSize * 1000 + "KB");const maxSize = this.maxSize || 500; //限制大小const isAllowSize = file.size / 1024 / 1024 <= maxSize;isFile || this.$message.error("上传文件只能是" + this.accept + "格式");isAllowSize || this.$message.error("上传文件大小不能超过" + maxSize + "MB");let allowUpload = isFile && isAllowSize && isAllowMinSize;if (allowUpload) {this.showFakeLoading(file);this.$nextTick(() => {this.$g.file2Base64Image(file, (d) => this.$emit(`resultBase64Image`, d));this.$emit(`beforeUpload`, file);});} else {this.hideFakeLoading(file, { type: "error", tip: "上传失败", color: "red" });}return allowUpload; //若返回false则停止上传},//上传成功uploadSuccess(response, file, fileList) {/* if ((this.drag === "" || this.drag) && this.isDragTrigger) {if (!file.isDragFile) return; //拖拽模式下,如果不是原生js捕获到的拖拽文件,就不进入上传队列(区别开两个el-upload组件避免重复上传)}*/if (response.data && response.data.key) {// 下载失败原因的描述文件/* this.$d.customer_downloadImportCustomerExcel({ key: response.data.key },{s: (d) => {this.$emit(`error`, response, file);this.hideFakeLoading(file, {type: "error",tip: "上传失败",color: "red",});this.$g.downloadFile(d, `${file.name}-上传失败原因`, ".xls");this.$message.error(`${file.name}-上传失败,请查看失败原因`);},}); */} else if (response.success) {this.$emit(`uploadSuccess`, response, file);// 上传成功了this.hideFakeLoading(file, { type: "success", tip: "上传成功", color: "green" });this.$message.success(`${file.name}上传成功`);} else {this.$emit(`uploadError`, response, file);// 其他失败原因this.hideFakeLoading(file, { type: "error", tip: "上传失败", color: "red" });}},//上传失败uploadError(err, file, fileList) {if (this.actionUrl === "#") return;if ((this.drag === "" || this.drag) && this.isDragTrigger) {if (!file.isDragFile) return; //拖拽模式下,如果不是原生js捕获到的拖拽文件,就不进入上传队列(区别开两个el-upload组件避免重复上传)}this.$emit(`uploadError`, err, file);this.hideFakeLoading(file, { type: "error", tip: "上传失败", color: "red" });this.$message.error("上传失败");},},};</script><style lang="scss">.sgDragUploadFolder {width: 0;height: 0;.el-upload-dragger {z-index: 999999; //根据情况自己拿捏position: absolute;width: 100%;height: 100%;left: 0;top: 0;display: none;background-color: #ffffff99;&::after {content: "拖拽文件到此处";position: absolute;width: 100%;height: 100%;display: flex;justify-content: center;align-items: center;color: #409eff;font-size: 18px;font-weight: bold;line-height: 1.2;}}&[dragenter] .el-upload-dragger {display: block;border-color: #409eff;&.is-dragover {background-color: #409eff22;&::after {content: "松掉鼠标上传文件";}}}}</style>

 应用

<template><div><div style="width:300px;height:300px;position: relative;"><img :src="src" style="width:100%;height:100%"><!-- 上传组件 --><sgDragUploadFolder drag ref="sgDragUploadFolder" :data="{accept: `*`,actionUrl: `${$d.API_ROOT_URL}/customer/importCustomerData`,}" @resultBase64Image="resultBase64Image" @success="uploadSuccess" @error="uploadError" hideUploadTray /></div><el-button type="primary" icon="el-icon-upload2" @click="d => $refs.sgDragUploadFolder.triggerUploadFile()">上传</el-button></div>
</template><script>
import sgDragUploadFolder from "@/vue/components/admin/sgDragUploadFolder";
export default {components: {sgDragUploadFolder,},data() {return {src: '',}},methods: {resultBase64Image(d, f) {this.src = d;},uploadSuccess(d, f) { }, uploadError(d, f) { },}
};
</script>

基于sgUpload升级改版你挚爱的强哥_Vue.js,JavaScript&TypeScript,CSS2/CSS3/LESS/SASS/SCSS/HTML-CSDN博客你挚爱的强哥擅长Vue.js,JavaScript&TypeScript,CSS2/CSS3/LESS/SASS/SCSS/HTML,等方面的知识,你挚爱的强哥关注css,html5,scss,firefox,elementui,正则表达式,stylus,csrf,express,intellij-idea,ajax,tdesign,ecmascript,edge,java,postman,webpack,electron,html,sass,firebug,github,chrome,spring cloud,layui,visualstudio,less,javascript,fiddler,eclipse,angular.js,angular,前端框架,node.js,chrome devtools,css3,gulp,safari,idea,mybatis,arco design,前端,es6,vue.js,turbopack,bootstrap,webkit,postcss,jquery,anti-design-vue,intellij idea,visual studio code,react.js,webstorm,git,echarts,json,xss,typescript,sublime text,myeclipse,coffeescript,编辑器,npm,reactjs,xhtml,easyui,spring boot,vscode,yarn,view design领域.https://blog.csdn.net/qq_37860634 

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

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

相关文章

.Net Core webapi RestFul 统一接口数据返回格式

在RestFul风格盛行的年代&#xff0c;大部分接口都需要一套统一的数据返回格式&#xff0c;那么我们怎么才能保证使用统一的json数据格式返回呢&#xff0c;下面给大家简单介绍一下&#xff1a; 假如我们需要接口统一返回一下数据格式&#xff1a; {"statusCode": …

智能图像编辑软件Luminar Neo mac提供多种调整和滤镜选项

Luminar Neo mac是一款由Skylum公司开发的AI技术图像编辑软件&#xff0c;旨在为摄影师和视觉艺术家提供创意图像编辑解决方案。Luminar Neo拥有强大的AI技术和丰富的后期处理工具&#xff0c;可帮助用户快速轻松地实现从基本到高级的图像编辑需求。 Luminar Neo提供了多种调整…

同步与互斥(二)

一、谁上锁就由谁解锁&#xff1f; 互斥量、互斥锁&#xff0c;本来的概念确实是&#xff1a;谁上锁就得由谁解锁。 但是FreeRTOS并没有实现这点&#xff0c;只是要求程序员按照这样的惯例写代码。 main函数创建了2个任务&#xff1a; 任务1&#xff1…

先进制造身份治理现状洞察:从手动运维迈向自动化身份治理时代

在新一轮科技革命和产业变革的推动下&#xff0c;制造业正面临绿色化、智能化、服务化和定制化发展趋势。为顺应新技术革命及工业发展模式变化趋势&#xff0c;传统工业化理论需要进行修正和创新。其中&#xff0c;对工业化水平的判断标准从以三次产业比重标准为主回归到工业技…

Kubernetes 容器编排(7)

离线业务编排详解 在线业务和离线业务 在线业务 Deployment、StatefulSet以及 DaemonSet 这三个编排概念的共同之处是&#xff1a;它们主要编排的对象&#xff0c;都是"在线业务"&#xff0c;即&#xff1a;Long Running Task&#xff08;长作业&#xff09;。比如…

尚硅谷 java 2023(基础语法)笔记

一、变量与运算符 1、HelloWorld的编写和执行 class HelloChina{public static void main(String[] args){System.out.println("hello,world!!你好&#xff0c;中国&#xff01;");} } 总结&#xff1a; 1. Java程序编写和执行的过程&#xff1a; 步骤1&#xff1…

HackTheBox - Medium - Linux - Sandworm (我的创作纪念日

Sandworm Sandworm 是一台中等难度的 Linux 机器&#xff0c;它托管了一个具有“PGP”验证服务的 Web 应用程序&#xff0c;该服务容易受到服务器端模板注入 &#xff08;SSTI&#xff09; 的攻击&#xff0c;导致“Firejail”监狱内的远程代码执行 &#xff08;RCE&#xff0…

12、Qt:用QProcess类启动外部程序:简单使用

一、说明 简单使用&#xff1a;在一个函数中&#xff0c;使用QProcess类的临时对象调用可执行文件exe&#xff0c;只有这个exe执行完了&#xff0c;这个函数才往下执行&#xff0c;一次性打印出exe所有输出信息&#xff1b;复杂使用&#xff1a;创建QProcess类的全局对象&…

STM32F4的DHT11初始化与实例分析

STM32—— DHT11 本文主要涉及STM32F4 的DHT11的使用以及相关时序的介绍&#xff0c;最后有工程下载地址。 文章目录 STM32—— DHT11一、 DHT11的介绍1.1 DHT11的经典电路 二、DHT11的通信2.1 DHT11的传输数据格式2.2 DHT11 通信分步解析 三、 DHT11 代码3.1 引脚图3.2 电路图…

阿里云林立翔:基于阿里云 GPU 的 AIGC 小规模训练优化方案

云布道师 本篇文章围绕生成式 AI 技术栈、生成式 AI 微调训练和性能分析、ECS GPU 实例为生成式 AI 提供算力保障、应用场景案例等相关话题展开。 生成式 AI 技术栈介绍 1、生成式 AI 爆发的历程 在 2022 年的下半年&#xff0c;业界迎来了生成式 AI 的全面爆发&#xff0c…

【接口测试】HTTP接口详细验证清单

概述 当我们在构建、测试、发布一套新的HTTP API时&#xff0c;包括我在内的大多数人都不知道他们所构建的每一个组件的复杂性和细微差别。 即使你对每一个组件都有深刻的理解&#xff0c;也可能会有太多的信息在你的脑海中出现。 以至于我们不可能一下把所有的信息进行梳理…

pycharm下执行conda命令提示无法识别解决方案

1 问题描述 win10环境命令行执行conda命令&#xff0c;报命令无法识别&#xff0c;错误信息如下&#xff1a; PS D:\code\cv> conda activate pt conda : 无法将“conda”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&a…

python基础语法总结

基础是深入必不可少的&#xff0c;如果没有基础的支持&#xff0c;后面都是浮云&#xff0c;就像情侣之间&#xff0c;没有感情基础是不会有好结果的&#xff0c;物资基础是靠两个人打拼的&#xff0c;所以学习就像谈恋爱&#xff0c;两个人要学会沟通&#xff0c;才能修成正果…

循环神经网络中的梯度消失或梯度爆炸问题产生原因分析(二)

上一篇中讨论了一般性的原则&#xff0c;这里我们具体讨论通过时间反向传播&#xff08;backpropagation through time&#xff0c;BPTT&#xff09;的细节。我们将展示目标函数对于所有模型参数的梯度计算方法。 出于简单的目的&#xff0c;我们以一个没有偏置参数的循环神经…

在Linux环境下模拟实现命令解释器用c语言实现mypwd「粉丝答疑」

粉丝提问 Solution 要在 Linux 环境下用 C 语言模拟实现一个命令解释器&#xff0c;包含mypwd, mymkdir, myrmdir, mycd, mylist, mycp, mydate, mycreate, mydelete, exit等基本命令&#xff0c;需要按照以下步骤进行&#xff1a; 理解每个命令的功能&#xff1a; mypwd: 显示…

SQL---Zeppeline前驱记录与后驱记录查询

内容导航 类别内容导航机器学习机器学习算法应用场景与评价指标机器学习算法—分类机器学习算法—回归机器学习算法—聚类机器学习算法—异常检测机器学习算法—时间序列数据可视化数据可视化—折线图数据可视化—箱线图数据可视化—柱状图数据可视化—饼图、环形图、雷达图统…

RTP/RTCP/RTSP/SIP/SDP/RTMP对比

RTP&#xff08;Real-time Transport Protocol&#xff09;是一种用于实时传输音频和视频数据的协议。它位于传输层和应用层之间&#xff0c;主要负责对媒体数据进行分包、传输和定时。 RTCP&#xff08;Real-Time Control Protocol&#xff09;是 RTP 的控制协议&#xff0c;…

TrustZone之可信操作系统

有许多可信内核&#xff0c;包括商业和开源的。一个例子是OP-TEE&#xff0c;最初由ST-Ericsson开发&#xff0c;但现在是由Linaro托管的开源项目。OP-TEE提供了一个功能齐全的可信执行环境&#xff0c;您可以在OP-TEE项目网站上找到详细的描述。 OP-TEE的结构如下图所示&…

Windows 系统彻底卸载 SQL Server 通用方法

Windows 系统彻底卸载 SQL Server 通用方法 无论什么时候&#xff0c;SQL Server 的安装和卸载都是一件让我们头疼的事情。因为不管是 SQL Server 还是 MySQL 的数据库&#xff0c;当我们在使用数据库时因为未知原因出现问题&#xff0c;想要卸载重装时&#xff0c;如果数据库…

vue element plus 管理系统路由菜单简要设计(后端获取菜单)

1 需求 管理系统“菜单”由后端接口返回&#xff0c;前端需要根据后端返回的“菜单”数组&#xff0c;构造路由&#xff0c;渲染侧栏菜单有些菜单是子菜单&#xff0c;有对应的路由&#xff0c;但是不在侧栏显示&#xff08;比如一些详情页面&#xff09; 注&#xff1a;这里的…