前言

上个文章介绍了多图片压缩,多图片可以通过直接多选图片进行拖拽,也可以通过直接拖拽文件夹进行解析得到多图片,接下来直接上代码

先展示文件拖拽后对文件的解析效果

图片文件夹

图片文件夹解析

大文件夹(包含280个文件)上传

280个文件解析

![在这里插入图片描述](https://img-blog.csdnimg.cn/8985bda3ac5a4c9da6ad79e62fceb9fd.png#pic_center

// 这里是template中代码
<divclass="middle-ccc":class="[{ 'drop-shadow': dropType === 'ccc' }]"@dragenter.stop.prevent="handlePictureBoxDragenter('ccc')"@dragover.stop.prevent=""@dragleave.stop.prevent="handlePictureBoxDragleave"@drop.stop.prevent="handlePictureBoxDrop($event, 'ccc')"
>// 内部代码省略</div>// 这里是vue3的js处理流程
const fileArrPromiseResolve = ref(null) // 图片文件上传的promise事件
const fileArrPromise = ref(null)// 设置文件加载的promise
const initFileArrPromise = () => {fileArrPromise.value = new Promise((resolve) => {fileArrPromiseResolve.value = resolve})
}// 文件拖拽dragenter进入
const handlePictureBoxDragenter = (type) => {// 这里传入一个10ms的延迟锁,让dragleave在enter延迟后触发pictureBoxLock.value = truesetTimeout(() => {pictureBoxLock.value = false}, 10)// dropType.value是文件拖拽进选中范围的高亮效果dropType.value = type
}// 文件拖拽dragleave离开
const handlePictureBoxDragleave = () => {// 多张图片拖拽进入的延迟锁时返回if (pictureBoxLock.value) returndropType.value = ''
}// 文件拖拽drop落下
const handlePictureBoxDrop = async (e) => {dropType.value = ''// 判断file是文件夹还是文件const isDirectory = e.dataTransfer.items[0].webkitGetAsEntry().isDirectory// 这里的file给了一个初始值,如果是单张或多张图片拖拽可以直接获取其files属性let file = e.dataTransfer.filesif (isDirectory) {// 这里对promise进行一个初始化initFileArrPromise()// 这里获取到文件的一个file信息const fileItems = e.dataTransfer.items[0].webkitGetAsEntry()// 这里是对fileItems处理,返回的是所有文件的数组file = await getFileDirectory(fileItems)}// 如果未能读取到想要的图片或者文件夹为空,都直接提示错误返回if (!file || !file.length) {ElMessage({ message: '图片上传错误', type: 'error' })return}console.log(file, 'file)
}// 这里对文件处理通过promise进行处理,为了确保文件夹中最后一个文件读取完成后再进行操作
const getFileDirectory = (fileItems) => {return new Promise((resolve) => {fileTypeLoop(fileItems, '', [])fileArrPromise.value.then((file) => {resolve(file)})})
}
//  TODO: 这段代码过于复杂,后面会考虑优化
// 文件夹上传解析,进行了递归和类型划分,返回fileArr数组
const fileTypeLoop = (fileItem, path, fileArr, loopOver = false) => {let dirReader = null// 如果fileItem是文件而不是文件夹进入if (fileItem.isFile) {fileItem.file((file) => {// fileTypeFilter方法是对你想要哪一类型的文件,我这里只想要图片格式const fileFilter = file.type && 'image/gif,image/jpeg,image/jpg,image/png,image/bmp'.indexOf(file.type) > -1if (fileFilter) {// 这里将路径重新进行整理fileItem.path = path + file.name// 重新创建file数据格式,加入type和path放入到fileArr中const newFile = new File([file], fileItem.path, { type: file.type })fileArr.push(newFile)}// 如果文件夹读到最后一个时,将fileArr数组通过resolve返回出去if (loopOver) fileArrPromiseResolve.value(fileArr)})} else if (fileItem.isDirectory) { // 如果fileItem是文件夹,读取文件夹内容再进行处理dirReader = fileItem.createReader()dirReader.readEntries(onReadEntries)}// 通过递归解析出文件夹中所有文件,readEntries正常只能读出100个文件// 项目中一个文件中有280个文件,能成功读取出function onReadEntries(entries) {for (let i = 0; i < entries.length; i++) {// 判断是否是最后一个文件,是的话就让loopOver为trueif (i === entries.length - 1 && !entries[i].isDirectory && entries.length < 100) loopOver = true// 进行递归处理fileTypeLoop(entries[i], path, fileArr, loopOver)}// 如果entries.length则说明文件中可能不止100个文件,这个时候需要继续嵌套读取if (entries.length) dirReader.readEntries(onReadEntries)}
}// 这里是style样式
.drop-shadow {box-shadow: 0px 0px 12px #18bae3;}

上述API的描述文档

webkitGetAsEntry:如果DataTransferItem描述的项目是一个文件,webkitGetAsEntry()返回一个表示它的FileSystemFileEntry或FileSystemDirectoryEntry。如果项目不是文件,则返回null

createReader:FileSystemDirectoryEntry接口的方法createReader()返回一个
FileSystemDirectoryReader对象,可用于读取目录中的条目

readEntries:FileSystemDirectoryReader接口的readEntries()方法检索正在读取的目录中的目录条目,并将它们以数组的形式传递给所提供的回调函数

e.dataTransfer:该DataTransfer对象用于保存在拖放操作期间被拖动的数据。它可以保存一个或多个数据项,每个数据项是一种或多种数据类型
具体参数:
(1)dataTransfer.dropEffect:获取当前选择的拖放操作的类型或将操作设置为新类型。该值必须是none、copy
(2)dataTransfer.effectAllowed
:提供所有可能的操作类型。必须是none, copy, copyLink, copyMove, link, linkMove, move,all
(3)dataTransfer.files
:包含数据传输中可用的所有本地文件的列表。如果拖动操作不涉及拖动文件,则该属性为空列表
(4)dataTransfer.items (只读)
:给出一个DataTransferItemList对象,它是所有拖动数据的列表
(5)dataTransfer.types (只读)
:dragstart一个字符串数组,给出在事件中设置的格式

vue对文件夹进行拖拽上传完整流程(文件夹中超出100个文件)相关推荐

  1. vue+flask实现视频合成(拖拽上传)

    vue+flask实现视频合成 效果如下 欢迎访问博客代码哈士奇 技术 聊天 交流群 974178910 前端交流群 535620886 vue+flask实现视频合成 拖拽上传我们之前一个文章有写过 ...

  2. js使用input上传文件夹、拖拽上传文件夹并将文件夹结构展示为树形结构

    一.实现效果 左侧区域支持选择一个系统中的文件夹,或者将文件夹拖拽到这个区域进行上传,右侧区域可以将文件夹的结构展示为树形结构. 二.代码实现 由于需要使用树形插件zTree,这个插件是依赖于jque ...

  3. java 拖拽上传_Java swing怎么实现上传文件并支持拖拽上传

    展开全部 你这个复杂了,我稍微说说吧. 进度条稍微简单点,你就去看看Oracle的tutorial就行了,记得运用科学(或32313133353236313431303231363533e78988e ...

  4. 拖拽上传及读取文件实现

    1.拖拽上传相关事件 2.拖拽上传简单实现 3.拖拽上传完整实现 4.读取文件实现 1.拖拽上传相关事件 相关事件: ondragenter 拖着东西进入 ondragleave 拖着东西离开 ond ...

  5. vue-simple-uploader实现多文件/文件夹以及可拖拽上传

    vue-simple-uploader的简单使用 1.效果图展示 2.安装 3.vue2使用(vue3使用会报错) 4.代码 vue-simple-uploader是基于simple-uploader ...

  6. js实现文件拖拽上传并显示待上传的文件列表

    此文章中完整的代码在我的github中:https://github.com/LiuFeng1011/WebTest/tree/master/upload 首先实现html页面的内容: <bod ...

  7. vue+element-ui实现富文本(含有图片粘贴拖拽上传)

    vue+element-ui实现富文本(含有图片粘贴拖拽上传) Just For Share | 仅仅分享 首先需要安装 cnpm i vue-quill-editor -D 富文本编辑器 cnpm ...

  8. html ajax打包成app,利用HTML5与ajax完成拖拽上传文件

    前言 基于ajax的异步模式的上传控件,基本功能如下: 拖拽上传(利用HTML5新增特定 拖拽事件 以及 event的dataTransfer属性) 单文件/多文件切换(利用php实现单/多文件上传) ...

  9. html5 上传超大文件,HTML5教程 如何拖拽上传大文件

    本篇教程探讨了HTML5教程 如何拖拽上传大文件,希望阅读本篇文章以后大家有所收获,帮助大家HTML5+CSS3从入门到精通 . < 前言: 大文件传输一直是技术上的一大难点.文件过大时,一些性 ...

最新文章

  1. 【408预推免复习】计算机网络(谢希仁第七版)第五章——运输层
  2. idea 引入oracle驱动并打包_IDEA下从零开始搭建SpringBoot工程
  3. Python----面向对象---自定义元类控制类的实例化行为的应用
  4. html4符合web的标准吗,在生成HTML,表格等时,CakePhp是否“符合标准”?
  5. (42)根据时钟关系分类时钟
  6. eclipse中server name选项变灰
  7. linux内容对齐的快捷键,linux第一波命令总结
  8. Windows 8 Directx 开发学习笔记(九)材质定义及混合光照效果实现
  9. ReactNative字体大小不随系统字体大小变化而变化
  10. 【leetcode】1018. 可被 5 整除的二进制前缀
  11. BZOJ1022 [SHOI2008]小约翰的游戏John (博弈论)
  12. pytorch数据集
  13. 计算机关闭节能模式,bios怎么关闭cpu节能模式_bios节能模式怎么设置
  14. 《艾伦图灵传:如谜的解谜者》阅读笔记
  15. python 求极值
  16. 忆亚强建筑预算软件的2001年半年时光
  17. 美国60所真正著名的大学
  18. Effect Size
  19. 医疗管理系统-图形报表、POI报表
  20. netty学习01--nio与oio的比较

热门文章

  1. icloud与mysql,在icloud中存储sqlite数据库?
  2. 网宿PHP工资应届生,IT 毕业生工资
  3. JS继承的6种方法详解以及优缺点对比
  4. android4版本的手机有,Android版本份额:还有两成人用安卓4.4
  5. java程序开发的三个步骤
  6. 怎么设置IP不会冲突,本地电脑为服务器时IP冲突解决方案!
  7. Linux的rz命令
  8. Torch 中添加自己的 nn Modules:以添加 Dropout、 Triplet Loss 为例
  9. java日志系统详解
  10. 【纯干货】微信支付接入攻略—JAVA代码分享