前言

首先说一下,小弟第一次写文章,如果有什么错误 还望小哥哥 小姐姐多多包涵。如果有什么缺陷还望大家指出来 让小弟多学习。

内容划分

上传文件夹一共分两部分来写 一方面怕太长了 大家看五分钟就不想看了 二是没有那么多时间写本文 所以分为两次 这两篇文章我只写上传文件夹重要的知识点内容 其他知识点就不细写了 我相信掘金肯定会有更优秀的文章

  • 上传文件夹的前期基础知识准备
  • 完成上传文件夹的功能的思路和遇到的问题

组件功能(主要满足公司的业务功能 文件夹里目前只带图片 如果有其他的文件 我会移除)

  • 可以拖拽上传文件夹 文件夹下面可以嵌套文件夹
  • 可以点击上传多图片
  • 可以一起拖文件夹和图片
  • 也有一些上传成功 失败 进度等等的回调

组件背景

公司业务需求 需要传很多图片而且有文件夹区分。所以要求做一个文件夹可以拖拽的组件。(因为人手不够加上公司定制化的东西多 所以我现在主要负责公司前端的组件开发 目前不写业务。这个也是我自己拦下的 虽然有时候比较难 但是能夯实很多基础知识 )

怎么写

之前只做过图片上传,但是没有做过文件夹上传。一时间不知道从何下手。怎么办 第一步就是看了一下某盘的上传操作。我试着拖动文件夹上传。整理了上传思路。

  • 首先读取到文件夹的名称 包括文件夹下面的文件夹 组成树形结构
  • 组成文件夹树形结构之后 遍历上传文件夹
  • 在服务器上创建同名文件夹
  • 再把文件夹的图片上传到同名文件夹下

整体思路就是这样。看着是不是很简单呢。。。对我来说 其实一点也不简单。 我写了一周才写完。。。不碰到难点的东西 都不知道自己弱。。

技术实现

首先基础拖拽drop等事件我就不说。掘金上面也有很多优秀的文章。我主要说一下文件夹名称的获取。 因为很多人发现拖拽通过 event.dataTransfer.files 可以读取文件夹名字 但是我们拿不到里面的文件啊!!!怎么办呢? 我们知道 dataTransfer.files 返回的是File对象。列表里面的每项是每个读取到的文件。里面包括name、type、size等属性。那么文件夹里面的文件怎么办呢。其实可以通过dataTransfer.items。它返回的是一个DataTransferItemList对象,表示在拖动操作中拖动的项目的对象。但是只有这个还不够。我们需要它的一个方法 webkitGetAsEntry() 来返回文件。这个方法是非标准的。这时候就判断是文件夹还是文件 通过 isDirectory 方法和 isFile 来判断,如果是文件夹目录。就需要递归得到该目录。 第一步是创建一个FileSystemDirectoryReader来处理目录内容。 通过createReder()方法来完成。 之后 readEntries()调用读取目录中的所有文件。 上面所有的内容我们都可以在MDN上找到 而且MDN上面也给了说明和代码示例。(非常感谢MDN)。接下来我贴一段代码示例

<div id="app"><div class="upload upload-box" id="upload">拖动文件夹到此处上传</div></div>复制代码

const upload = document.getElementById('upload');upload.addEventListener('dragover', uploadFunc, false);
upload.addEventListener('drop', uploadFunc, false);function uploadFunc(event) {event.preventDefault();let files = [];if (event.type === 'drop') {let fileList = event.dataTransfer.files;let len = fileList.length;for (let i = 0; i < len; i++) {files[i] = fileList[i];}if (files.length) {let items = event.dataTransfer.items;if (items && items.length && items[0].webkitGetAsEntry != null) {addFilesItems(items);}}}
}function addFilesItems(items) {return function() {var ret = [];for (var i = 0; i < items.length; i++) {var item = items[i];var entry;if (item.webkitGetAsEntry && (entry = item.webkitGetAsEntry())) {if (entry.isFile) {// 把文件对象放到结果数组中  这里的addFile方法要单独写 我没有写上 这个不是重点ret.push(addFile(item.getAsFiles()));} else if (entry.isDirectory) {ret.push(addFilesFormDirectory(entry, entry.name));}}}}();} // 读取文件夹下的文件
function addFilesFormDirectory(directory, path) {const dirReader = directory.createReader();const readEntries = function readEntries() {return dirReader.readEntries(function(entries) {entries.forEach(function(entry){if (entry.isFile) {// 如果是文件entry.file(function(file){file.fullPath = path + '/' + file.name;// 那么暴露出去的就是 '文件夹/q.jpg' 这种形式 return addFile(file);});return addFile(file);} else if (entry.isDirectory) {// 递归处理addFilesFormDirectory(entry, path + '/' + entry.name);}});});};return readEntries();
}
复制代码

通过readEntries会读取到下面的内容

上面就是拖拽上传文件夹需要准备的知识点。

最后

其实文件夹上传只是在服务器创建一个名字。用一个字段告诉我这是文件夹。难点在于怎么先创建好文件夹 在把客户端这个文件夹下面的文件上传到创建好的文件夹下面。还有FileReader相关的知识点 大家可以去高程书里面的25章节里面查看。里面写的很详细。再配合上饿了么上传组件的源码就更完美。我相信如果你仔仔细细阅读完它的源码 并自己实现一个上传组件,我相信你能学到更多,反正我是看完它的源码写了一个上传组件。写完之后 感觉真香。。。。

总结

这些知识点都是我查阅很多资料整理的,而且告诉大家一个秘密。有一个dropzonejs的库。 我的项目就是基于它实现的。有很多完整的功能帮助我完成上传文件夹组件。因为有些功能我自己写会很费时间而且有的不一定会写 所以我就直接使用它的API 阅读了它的源码。你也可以去看看官方文档 最后谢谢dropzone

过几天我会更新下一篇 实现上传文件夹的一些思路和遇到问题。下一篇也会把这个项目开源到我的github。

转载于:https://juejin.im/post/5c09e224f265da61493371f7

拖拽文件夹上传 一(基于Vue的文件夹上传组件)相关推荐

  1. vue可视化拖拽生成工具_GitHub - 1260215278/dragUI: 基于vuedraggable.js + uni 的可视化拖拽编程,自动生成项目,自动生成代码,自行导入第三方组件...

    dragUI 用于UNI可拖拽可视化编程 在线演示 效果图 基于 快速开始 参考uni官网安装普通uni项目(运行uni-app)运行到浏览器 另需要手动下载包npm install 项目目录 col ...

  2. 史上最全基于vue的图片裁剪vue-cropper使用

    史上最全基于vue的图片裁剪vue-cropper使用 基于vue的图片裁剪vue-cropper 新的需求 vue-cropper官网 代码拷贝 最后 基于vue的图片裁剪vue-cropper 最 ...

  3. Element 2.6.0 发布,基于 Vue 2.0 的桌面端组件库

    开发四年只会写业务代码,分布式高并发都不会还做程序员?   Element 2.6.0 发布了,Element 是一套为开发者.设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库,提供了配套设 ...

  4. vue前端上传文件夹的插件_基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件...

    1. 前言 之前公司要在管理系统中做一个全局上传插件,即切换各个页面的时候,上传界面还在并且上传不会受到影响,这在vue这种spa框架面前并不是什么难题.然而后端大佬说我们要实现分片上传.秒传以及断点 ...

  5. antd upload手动上传_基于MVVCTP5的文件上传

    现如今在市面上常见的web开发理念一般是两种,一种是MVC格式的,比较传统,而项目较大的开发,一般由团队完成,而MVC格式就显得有些不够合理 .于是 ,在这种情况下诞生了另外一种开发理念,我们叫MVV ...

  6. 笔记十三 :Egret拖拽对象与吸附对象(基于通用MVC框架)

    前言:拖拽对象是2D游戏中常用的一个功能,例如<植物大战僵尸>中种植植物的表现形式,拖拽植物卡片种植到相应的地点. 思路:在Egret中实现拖拽对象,需要用到TOUCH_MOVE事件的监听 ...

  7. 【计算机图形】制作能够利用鼠标拖拽实现360度旋转的3D人体模型flash文件

    前段时间,由于要对参加挑战杯的系统进行改善,老师要求我们在系统当中添加一个可旋转的3D人体模型,于是俺陷入了深深的思考当中.之前一直都没有接触过3D模型的制作,而且老师这回给的时间又特紧,当时那个急呀 ...

  8. springboot基于vue.js的掌上博客系统的设计与实现毕业设计源码063131

    Springboot掌上博客系统的设计与实现 摘 要 掌上博客系统是当今网络的热点,博客技术的出现使得每个人可以零成本.零维护地创建自己的网络媒体,Blog站点所形成的网状结构促成了不同于以往社区的B ...

  9. (附源码)springboot基于vue.js的掌上博客系统的设计与实现 毕业设计 063131

    Springboot掌上博客系统的设计与实现 摘 要 掌上博客系统是当今网络的热点,博客技术的出现使得每个人可以零成本.零维护地创建自己的网络媒体,Blog站点所形成的网状结构促成了不同于以往社区的B ...

最新文章

  1. SecutrCRTt 连接VirtualBox 中的Ubuntu -端口转发
  2. Linux 配置iso系统盘为本地yum源
  3. SpringMVC+JWT+Swagger UI+RestFul
  4. HttpClient 使用
  5. 字典的增删改查/元组的创建
  6. gc:C语言的垃圾回收库-英文
  7. sql server死锁_SQL Server死锁定义和概述
  8. 注册中验证码实现(项目案例)
  9. python工时计算_敏捷开发项目人力工时评估法则
  10. gigabyte计算机主板图解,gigabyte主板bios设置方法
  11. 服务器虚拟系统无法上网络设置,玩转Windows 2008虚拟机网络设置
  12. 运放的参数详解及应用电路
  13. 转载一个特征提取的方法——AE
  14. SAP BW报表使用操作手册——系统登录
  15. input文本框实现输入英文时自动触发事件,输入中文时要输入完成后才触发事件
  16. STM32CubeIDE HAL库IIC实现气压计MS5637的数据读取
  17. 华为服务器pe下安装linux,华为服务器安装操作系统.docx
  18. git 如何提交丰富的emoji表情
  19. BasicSRSuper-resolution——Video2video
  20. msk 频偏_一种直扩MSK信号的二维联合捕获方法

热门文章

  1. 迭代器模式-前端设计模式
  2. 超有效的Linux死机解决方法
  3. zoj - 1940 - Dungeon Master
  4. 最新的linux学习路线图
  5. OIS几个重要的类的使用
  6. 十大经典零食,你吃过几样?
  7. 老照片电子修复后丢失能找回吗
  8. 什么是JVM?什么是JDK? 什么是JRE?
  9. 软件公司(company)
  10. 函数局部有界性定理_函数极限的局部有界性的证明