相关对象 File Blob FormData FileReader,其中File 对象是 Blob 的子类,所以可以直接使用Blob对象的slice方法,分片操作主要用slice方法实现
<template>
<div>
<input type="file" name="file" @change="fileChange" multiple />
<div>{{ precent }}%</div>
<span v-for="item in imgList" :key="item">{{ item.name }}</span>
<img style="width: 200px" :src="imgbase64" />
<button @click="submit">提交</button>
</div>
</template>
<script>
import axios from "axios";
import { fstat } from "fs";
let _fileObj;
export default {
name: "HelloWorld",
data() {
return {
imgbase64: "",
imgList: [],
precent: 0,
};
},
methods: {
fileChange(e) {
let file = e.target.files[0]; //获取file对象中的第一个文件
_fileObj = file;
//如对文件有一定要求可通过形如下列判断
if (file.size > 10 * 1024 * 1024) {
alert("文件不能大于十兆");
}
if (file.type !== "video/mp4") {
alert("必须是mp4");
}
let _sliceBlob = new Blob([file]).slice(0, 5000); //Blob和File对象第一项必须都是传入一个数组,使用slice方法则可实现分片
let _sliceFile = new File([_sliceBlob], "test.png"); //File和Blob可以实现对象间的相互转化 File=>Blob或Blob=>File
let fr = new FileReader();
fr.readAsDataURL(_sliceFile); //使用FileReader对象的方法将file转为base64
let self = this; //普通函数内this指向会改变
fr.onload = function () {
self.imgbase64 = fr.result;
};
//怎么做缩略图,文本预览
//多文件上传
if (e.target.files.length > 1) {
this.imgList.concat(e.target.files);
} else {
this.imgList.push(e.target.files[0]);
}
//切片上传
_fileObj = e.target.files[0];
},
async submit() {
this.imgList.forEach((item) => {
let _formData = new FormData();
//_formData.append("user", "asdasd");
_formData.append(item.name + "file", item);
axios.post("/xx", _formData); //后端一般接受formData对象或者用FileReader转换后的对象
});
let size = 2 * 1024 * 1024; //限制每次传2兆
let fileSize = _fileObj.size; //文件总大小
let current = 0; //当前是第几兆(传了多少)
//localStorage.setItem(_fileObj.name, current); //断点续传
while (current < fileSize) {
//如果当前传的大小小于文件总大小则继续
let _formData = new FormData();
_formData.append(
_fileObj.name, //后端根据文件名来合并文件
_fileObj.slice(current, current + size) //每次分片传哪部分 假如文件有7兆 0-2 2-4 4-6 6-8(即使到7就结束了也不会报错,会完整上传)
);
await axios.post("http://localhost:4000/upload", _formData); //一次一次发请求传递给后端
this.precent = Math.min((current / fileSize) * 100, 100); //当前上传进度
current += size; //每次加上分片大小
}
},
},
};
// 1,单多文件上传,切片上传,断点续传 2,file blob fileReader formdata
</script>
各对象间的转换关系如下图