博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
拖拽文件夹上传 一(基于Vue的文件夹上传组件)
阅读量:7023 次
发布时间:2019-06-28

本文共 3569 字,大约阅读时间需要 11 分钟。

前言

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

内容划分

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

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

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

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

组件背景

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

怎么写

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

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

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

技术实现

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

拖动文件夹到此处上传
复制代码
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

你可能感兴趣的文章
19. Spring Boot Shiro 权限管理
查看>>
【C语言】14-返回指针的函数与指向函数的指针
查看>>
uoj#119. 【UR #8】决战圆锥曲线(线段树+复杂度分析)
查看>>
docker 13 dockerfile的保留字指令
查看>>
(转)开放window是服务器端口——以8080为例
查看>>
C# 通过IEnumberable接口和IEnumerator接口实现泛型和非泛型自定义集合类型foreach功能...
查看>>
微信小程序初识
查看>>
Ubuntu中打开RAR文件
查看>>
数字转换大写人民币的delphi实现
查看>>
开源的asp.net工作流程引擎。 http://ccflow.org
查看>>
日期和时间字符串格式化
查看>>
POJ2774:Long Long Message——题解
查看>>
javascript作用域与预解析
查看>>
C# 中的拓展方法,以StringBuilder加上IndexOf方法举例
查看>>
第41件事 创新设计的4种方法
查看>>
iOS--CollectionView添加类似TableView的TableViewHeaderView 和 SectionHeader 的置顶悬停效果...
查看>>
用半监督算法做文本分类
查看>>
【2802】SDUTOJ (并查集模板水题2)
查看>>
看书不挑出版社的都是山炮——评60家国内出版社
查看>>
326. Power of Three
查看>>