需求:点击页面按钮上传文件夹,但是需要经过前端压缩后再上传到服务器(至于为什么不先打好压缩包再直接上传,领导的意思是他要上传的文件在本地是加密的,上传到浏览器的文件是解密的,并不是很懂但是需求还是得完成)
1.首先下载所需要的插件jszip和FileSaver
npm install jszip
npm install file-saver //主要用来下载文件验证上传是否正确,不是刚需
//页面引入
import JSZip from "jszip";
import FileSaver from "file-saver";
2.页面标签的话只需要一个button按钮即可
<el-form-item label="上传模板:" prop="fileName">
<el-button @click="handleChange">上传文件夹el-button>
el-form-item>
3.完整代码
handleChange() {
let input = document.createElement("input");
input.type = "file";
input.setAttribute("allowdirs", "true");
input.setAttribute("directory", "true");
input.setAttribute("webkitdirectory", "true"); //设置了webkitdirectory就可以选择文件夹进行上传了,el-upload也适用但方法不一样
input.multiple = false;
document.querySelector("body").appendChild(input);
input.click();
let _this = this;
input.onchange = async function (e) {
let file = e.target["files"];
let path = file[0].webkitRelativePath; //取path是为了获取上传的文件夹一级的名称
let name = path.split("/")[0];
console.log(name);
let zip = new JSZip();
_this.forEachZip(zip, file); //处理文件夹里的所有子文件
// 生成压缩文件
zip.generateAsync({ type: "blob" }).then((content) => {
//将blob类型的再转为file类型用于上传
let zipFile = new File([content], `${name}.zip`, {
type: "application/zip",
});
//做个大小限制
let isLt2M = zipFile.size / 1024 / 1024 < 80;
if (!isLt2M) {
_this.fileList = [];
_this.$message({
message: "上传文件大小不能超过 80MB!",
type: "warning",
});
return false;
} else {
let filedata = new FormData();
filedata.append("file", zipFile);
_this.handlesubmit(filedata); //这个地方换成自己的上传事件即可,filedata已经是压缩好的文件了
// FileSaver.saveAs(content, `${name}.zip`); //下载用,可以下载下来文件查看上传的是否正确
}
});
document.querySelector("body").removeChild(input);
};
},
forEachZip(zip, files) {
for (let i = 0; i < files.length; i++) {
//通过path将文件夹里的所有子文件归类处理,主要是为了保持上传后的文件夹目录保持不变
zip.file(files[i].webkitRelativePath, files[i]);
//如果想上传后将里面的所有文件夹都归类到一级可以用下面的方式
// let file = files[i];
// zip.file(file.name, file);
}
},