Element ui附件可以一次上传多次但只请求一次,直接与前端交互上传到系统。
需求:选择文件后直接上传到系统,不再有多余的按钮触发
实现方式:element ui upload组件的多附件上传循环调用upload socket,每次on-change变化后调用前端socket进行交互。
问题:多次调用前端socket会导致前端socket并发报错。
解决方案:如果想一次性传输多个上传的附件到前端,只需要调用一次socket即可,但是不知道socket调用动作是什么时候触发的,所以需要知道选择的文件个数。 当选择的文件数等于上传的文件数时elementui 与后台交互,超过文件数时才可以调用socketelementui 与后台交互,并且上传socket请求必须自定义,不能循环调用。 否则,套接字是异步请求的,仍然无法知道所有调用何时完成。
代码:
<el-upload
class="upload-demo"
:auto-upload="false"
multiple
action="#"
:file-list="fileList"
:on-change="handleChange"
:show-file-list="false"
:disabled="uploadLoading"
style="width: 120px"
>
<el-button style="float: left" size="small" v-if="isShowUploadBtn" :loading="uploadLoading">
<el-icon class="el-icon-paperclip"></el-icon>
<label class="table-head-button-lable">{{ btnMsg || t('上传附件') }}</label>
</el-button>
</el-upload>
setup(props, { emit }) {
let uploadLoading = ref(false);
const addNum = ref(0);
const num = ref([]);
const handleChange = async (file) => {
// 上传即提交,判断选取文件数量等于上传次数再提交,避免分开调用后端并发报错
if (props.isUploadAndSubmit) {
uploadLoading.value = true;
var upload_img = document.getElementsByClassName('upload-demo');
let uploadNum = 0;
if (upload_img && upload_img.length > 0) {
var upload = upload_img[0].getElementsByTagName('input');
if (upload && upload.length > 0 && upload[0].files && upload[0].files.length > 0) {
uploadNum = upload[0].files.length;
}
}
addNum.value++;
num.value.push(file);
if (addNum.value == uploadNum) {
const formData = new FormData();
num.value
.filter((n) => !n.fileUrl)
.forEach(async (item) => {
formData.append('fileList', item.raw);
});
let res = await uploadFileList(formData);
if (res) {
res.forEach((r) => {
fileList.value.push(r);
});
emit('handleAdd', res);
addNum.value = 0;
num.value = [];
}
}
uploadLoading.value = false;
} else {
}
}
};
return {
handleChange
};
}