当文件过大上传时,需要很长时间,用户如果点击取消上传,但是接口还在pending,所以需要在点击取消上传的时候终止请求
其实问题是因为我们表单涉及到上传是:需要上传的时候先调上传的api,后端返回一个当前上传文件的Id,再在表单提交的时候携带这个fileId提交过去
好处就是:不需要在表单的上传的时候new formData,在append(我个人感觉好处是这个)
思路
我是一个表单有多个upload文件。所以formRef定义了两个fileId和fileList
javascript
import { reactive } from "vue";
const formModel = reactive({
name: "",
fileId: "",
modelConfigFileId: "",
fileList: [],
fileConfigList: []
});
上传使用的方法是upload的http-request api,取消上传使用的是on-removeapi
template代码
javascript
<el-form
ref="ruleFormRef"
:model="formModel"
>
<el-form-item label="Model name" prop="name">
<el-input v-model="formModel.name" />
</el-form-item>
<el-form-item label="File " prop="fileList">
<el-upload
v-model:file-list="formModel.fileList"
:http-request="
options => customCommonUpload(options, { type: 'fileList' })
"
:on-exceed="handleExceed"
:on-remove="file => removeCommonFile(file, { type: 'fileList' })"
:limit="1"
>
<template v-slot:trigger>
<el-button type="primary">select file</el-button>
</template>
</el-upload>
</el-form-item>
<el-form-item label="config File" prop="fileConfigList">
<el-upload
v-model:file-list="formModel.fileConfigList"
:http-request="
options => customCommonUpload(options, { type: 'fileConfigList' })
"
:on-exceed="handleExceed"
:on-remove="file => removeCommonFile(file, { type: 'fileConfigList' })"
:limit="1"
>
<template v-slot:trigger>
<el-button type="primary">select file</el-button>
</template>
</el-upload>
</el-form-item>
</el-form>
script代码
javascript
const uploadCancelTokenSource = ref<any>(null);
const uploadConfigCancelTokenSource = ref<any>(null);
//上传文件
const customCommonUpload = async (
options: { file: File },
params: { type: string }
) => {
const { file } = options;
const { type } = params;
const formData = new FormData();
formData.append("file", file); // 添加文件到表单数据中
try {
// 使用 axios 或其他 HTTP 库来发送请求
uploadConfigCancelTokenSource.value = axios.CancelToken.source();
uploadCancelTokenSource.value = axios.CancelToken.source();
const response = await axios({
method: "post",
url: "your api", // 替换为你的上传地址
data: formData,
cancelToken:
type == "fileList"
? uploadCancelTokenSource.value.token
: uploadConfigCancelTokenSource.value.token
});
// 上传成功的处理逻辑
if (type == "fileList") {
formModel.fileId = response.data.result[0].fileId;
} else if (type == "fileConfigList") {
formModel.modelConfigFileId = response.data.result[0].fileId;
}
console.log(formModel, "formModel==========");
return response;
} catch (error) {
// 上传失败的处理逻辑
if (axios.isCancel(error)) {
console.log("Request canceled", error.message);
} else {
console.error("Error uploading file:", error);
}
throw error;
}
};
//取消上传
const removeCommonFile = (uploadFile: UploadFile, params: { type: string }) => {
const { type } = params;
if (type == "fileList") {
// 如果有正在进行的上传请求,取消它
if (uploadCancelTokenSource.value) {
uploadCancelTokenSource.value.cancel("File upload canceled");
uploadCancelTokenSource.value = null;
}
// 更新文件列表
const index = formModel.fileList.indexOf(uploadFile);
if (index !== -1) {
formModel.fileId = "";
formModel.fileList.splice(index, 1);
}
} else if (type == "fileConfigList") {
// 如果有正在进行的上传请求,取消它
if (uploadConfigCancelTokenSource.value) {
uploadConfigCancelTokenSource.value.cancel("File upload canceled");
uploadConfigCancelTokenSource.value = null;
}
// 更新文件列表
const index = formModel.fileConfigList.indexOf(uploadFile);
if (index !== -1) {
formModel.modelConfigFileId = "";
formModel.fileConfigList.splice(index, 1);
}
}
};
const handleExceed = (files, fileList) => {
ElMessage.warning(`当前限制选择 1 个文件,请先删除已上传的文件`);
};