首先拖拽文件夹上传的文件夹对象里面是没有文件的!
然后就简单了!其实是利用 createReader, 调用目录的 createReader 方法,它会返回一个 DirectoryReader 对象,然后调用这个 DirectoryReader 对象的 readEntries 方法,可以得到目录所包含的项目!
那么原理就是
1、拖拽后判断内容里面是否是目录,如果是目录,就执行方法,如果是文件就直接加入列表
2、目录就执行createReader,读取到目录下所有内容后,再判断是否有目录,再不断的递归即可!
3、然后就拿文件列表,进行处理上传即可!
一、html
<div class="drops" @drop="handleDrop" @dragover="handleDragover" @dragenter="handleDragover" > <div class="upload-text"> 将文件拖到此处</div> </div>
二、js
// 拖拽上传 async handleDrop(e) { e.stopPropagation() e.preventDefault() let { items } = e.dataTransfer // 注意这里,是读取items属性 if (items && items.length && items[0].webkitGetAsEntry != null) { this.addFilesItems(items) } return false }, handleDragover(e) { e.stopPropagation() e.preventDefault() e.dataTransfer.dropEffect = 'copy' }, // 把读取到的文件加入一个对象内,这里是我的逻辑,可自行根据自己逻辑修改 getFile(files) { console.log(files) for (let i = 0, len = files.length; i < len; i++) { const uid = Date.now() + '' + this.tempIndex++ const obj = {} obj.name = files[i].name obj.size = files[i].size obj.value = files[i] obj.path = this.file_path // 拖拽文件夹上传的是fullPath if (files[i].webkitRelativePath || files[i].fullPath) { const filepaths = files[i].fullPath || files[i].webkitRelativePath // 如果是子文件夹!则把路径携带进去 obj.path = this.file_path + '/' + getFilePath(filepaths).replace(/^(\/)?|(\/)$/g, '') } console.log(this.file_list) obj.status = 0 this.$set(this.listObj, uid, obj) } }, // 循环判断拖拽来的是文件还是文件夹 addFilesItems(items) { const that = this 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) { // 如果是文件,直接加进去 that.getFile([entry]) } else if (entry.isDirectory) { // 递归文件夹 that.addFilesFormDirectory(entry, entry.name) } } } }, // 读取文件夹下的文件 addFilesFormDirectory(directory, path) { const dirReader = directory.createReader() const that = this dirReader.readEntries(function (entries) { entries.forEach(function (entry) { if (entry.isFile) { // 如果是文件 entry.file(function (file) { // 如果是点击上传文件夹 文件会携带webkitRelativePath ,拖拽则没有! // webkitRelativePath 没有set方法,需要添加个fullPath属性,才能得到递归的目录 file.fullPath = path + '/' + file.name that.getFile([file]) // 我的getFile 是接收数组,方便点击多传的时候一起传过去 return file }) } else if (entry.isDirectory) { // 递归处理 addFilesFormDirectory(entry, path + '/' + entry.name) } }) }) },