最近做了一个后台系统,里面有好多复杂的功能。其中就有上传的功能点,上传的时候,我们要校验上传的文件格式,限制上传的数量,自定义上传接口,可以拖拽上传,可以进行删除、预览,删除之后再次上传的时候会重现计算(这个时候要清除前一次上传的缓存列表)等等,于是就把这块好好总结一下,后面再用到就直接搬就行了。
上传功能
<el-table-columnprop="dataUpload"label="资料上传"width="440"><template #default="{ row }"><el-uploadclass="upload-demo"dragaction="#"multiple:disabled="isEdittable != 'true'":show-file-list="false":http-request="(file) => uploadfile(file, row)":before-upload="(file) => beforeUpload(file, row)":limit="row.docType == 'other' ? 999 : 1":on-exceed="exceedFile":ref="(el) =>setRefs(el,row.id)"><el-icon class="el-icon--upload"><upload-filled/></el-icon><divclass="el-upload__text">拖拽图片到此处,或<em>点此处选择文件</em></div></el-upload></template></el-table-column>
<script setup>
// 获取当前上传文件的html元素
const setRefs = (el, id) => {if (el) {if (!itemRefs.value.some((item) => item.id == id)) {itemRefs.value.push({id: id,el,});}}
};
//上传文件前校验文件类型
const beforeUpload = (file, row) => {// 做上传前的一些校验操作
};
// 超出限制文件数量的钩子函数
const exceedFile = () => {message.warning("只能上传一个文件");
};// 上传文件处理函数
const uploadfile = async (file, row) => {if (file.file.size == 0) {return message.warning("文件内容为空,无法上传");}form.set("file", file.file);form.set("type", row.type);form.set("id", row.id);form.set("docType", row.docType);const loading = loading.service({fullscreen: true,background: "rgba(0,0,0,0.7)",text: "文件上传中",});try {const res = await API.upload(form);if (res.data.code === "000000") {row.files.push({name: res.data.name,id: res.data.id,nailid: res.data.nailid,nailid: res.data.nailid,});loading.close();message.success("文件上传成功");} else {message.error(res.data.message);}} catch (error) {loading.close();message.error("文件上传失败请重试");} finally {loading.close();if (itemRefs.value.length > 0) {itemRefs.value.forEach((item) => {if (item.id == row.recordItemId) {item.el.clearFiles();}});}}
};
</script>
首先我用的ui组件是elementPlus,所以标签名是el-upload;
1、实现拖拽
如果要实现拖拽功能,需要给el-upload标签加上drag属性;
2、实现多选
如果要实现上传时多选文件的功能,需要给el-upload标签加上multiple属性;
3、控制是否可以编辑的功能
如果要实现是否可以上传,需要给el-upload标签加上disabled属性;
4、实现自定义上传操作功能
如果要实现自定义上传操作(自己写函数,并定义上传接口),需要给el-upload标签加上http-request属性,并赋予它对应的方法;
5、实现上传之后的校验操作功能
如果要实现上传前做校验,需要给el-upload标签加上before-upload属性,并赋予它对应的方法;
6、实现上传时限制的上传文件数量
如果要实现上传时限制上传的文件数量,需要给el-upload标签加上limit属性;
7、实现上传时当超出限制时,执行的钩子函数
如果要实现上传时超出限制上传的文件数量时,,需要给el-upload标签加上on-exceed属性,加上对应的钩子函数即可;
8、如果要获取到这个上传文件这个元素,需要加上ref
如果要获取上传文件的这个html元素,需要加上ref这个属性,但是因为上传文件el-upload这个元素是相当于v-for这样生成的,所以会获取到许多el-upload元素,这个时候需要有唯一的id和对应的el-upload元素来一一对应,所以会有一个id来对应;
下载功能
对于下载,后端返回的都是一个文件流,所以要对文件流做处理;
// 处理下载文件的方法
function downLoadXls(res) {const fileNames = res.headers["content-disposition"];if (fileNames) {//解码const fileName = decodeURIComponent(fileNames.match(/=(.*)$/)[1]);// 处理返回的文件流const content = res.data;const blob = new Blob([content], {type: "application/octet-stream; charset=utf-8",});if ("download" in document.createElement("a")) {//非IE下载const a = document.createElement("a"); //创建一个a标签a.download = fileName; //指定文件名称a.style.display = "none"; //页面隐藏a.href = URL.createObjectURL(blob); // href用于下载地址document.body.appendChild(a); //插到页面上a.click(); //通过点击触发URL.revokeObjectURL(a.href); //释放URL 对象document.body.removeChild(a); //删掉a标签} else {//IE10 + 下载navigator.msSaveBlob(blob, fileName);}}
}