**项目中碰到的需要,做一个类似svn的拖拽上传文件及文件夹,首先想到了vue-simple-uploader;vue-simple-uploader就是一个基于simple-uploader.js 和 Vue结合做的一个上传组件,自带 UI,可覆盖、自定义。 它支持文件、多文件、文件夹上传;支持拖拽文件、文件夹上传;可暂停、继续上传;支持秒传;上传队列管理,支持最大并发上传;分片上传;支持进度、预估剩余时间、出错自动重试、重传等操作(具体的使用方法就不多介绍了)。
虽然插件很强大,但是如果时空文件夹或者文件夹中存在空文件夹就不会触发上传操作了,因为文件夹上传的本质也是文件上传,然后根据目录结构组成文件夹。
最后使用了原生的拖拽,监听放置drop事件,配合插件共同完成了项目的上传需求。**
复制代码
首先在mounted中监听拖拽的放置事件
document.getElementById('uploader').addEventListener("drop", e => {
//uploader为拖拽放置的位置
});
复制代码
然后使用DataTransfer()构造函数,创建并返回一个新DataTransfer
对象。该**DataTransfer
**对象用于保存在拖放操作期间被拖动的数据。它可以保存一个或多个数据项,每个数据项是一种或多种数据类型
document.getElementById('uploader').addEventListener("drop", e => {
let items = e.dataTransfer.items;// `items`属性是 拖动操作list中的数据传输项的一个.该列表为操作中的每个项目包含一个项目,如果该操作没有项目,则列表为空。
let files = e.dataTransfer.files; //对象的**`files`**属性是在拖动操作中。如果操作不包含文件,则列表为空
for (let i = 0; i < items.length; i++) {
let item = items[i];
if (item.kind === "file" && item.type == '' && !files[i].relativePath) {
let entry = item.webkitGetAsEntry();
this.recursionFile(entry) //定义的递归方法
}
}
e.preventDefault();
});
复制代码
如果 描述的项目DataTransferItem是一个文件,则webkitGetAsEntry()
返回一个FileSystemFileEntry或FileSystemDirectoryEntry表示它。如果项目不是文件,null
则返回。
在methods中定义的一个递归方法,来执行多层文件夹操作
recursionFile(file) {
let aaa = file.createReader(); //createReader() 返回一个FileSystemDirectoryReader对象
aaa.readEntries((j) => { //readEntries()方法检索正在读取的目录中的目录条目,并将它们以数组的形式传递给提供的回调函数
j.forEach(fileItem => {
if (!fileItem.isFile) { //如果遍历的对象不是文件,则继续执行createReader()方法
let folderContents = fileItem.createReader();
folderContents.readEntries((i) => {
if (i.length == 0) { //如果文件的目录为0,则表示此为空的文件夹,执行相应的上传操作,其实就发送一个空文件夹的目录
let formData = new FormData();
formData.append('xxx', x)
formData.append('xxxx', xx)
formData.append('xxxxx', xxx)
uploadFlie(formData).then(res => {
if (res.code == 0) {
console.log('上传成功')
}
})
} else {
this.recursionFile(fileItem) //如果目录不为空,则继续递归
}
})
}
})
})
},
复制代码
该FileSystemDirectoryEntry接口的方法 createReader()
返回一个 FileSystemDirectoryReader对象,该对象可用于读取目录中的条目
该FileSystemDirectoryReader接口的**readEntries()
** 方法检索正在读取的目录中的目录条目,并将它们以数组的形式传递给提供的回调函数。
数组中的对象都是基于FileSystemEntry. 通常,它们要么是FileSystemFileEntry代表标准文件的对象,要么是FileSystemDirectoryEntry代表目录的对象。
此方法只为找出空文件夹,文件的上传是vue-simple-uploader执行的,不做赘述。