- 实现文件上传显示进度条功能 上传中显示进度条
上传完成后显示文件列表,进度条隐藏
主要用到了 :on-change, :before-upload, 另外也可以使用:on-progress,但是不知道为什么这个事件不触发?
根据索引动态生成 upload ref 的方法
// 使用 ref 创建一个空的对象,用于存储 el-upload 组件的 ref 引用
const uploadRefs = ref<any>({});
// 根据索引动态生成 upload ref 的方法
const getUploadRef = (index: any) => {
return (el: any) => {
// 将 el-upload 组件的 ref 引用存储到 uploadRefs 对象中
uploadRefs.value[index] = el;
};
};
调用方法:
// 文件上传前的钩子函数,这个时候已经选完文件了
const beforeUpload = (params, index) => {
// 选完上传的文件,开启进度条
uploadList[index].isShowJinDuTiao = true;
uploadList[index].curPercentage = 0;
uploadList[index].isDisabled = true;
};
// 文件上传中
const handleFileChange = (params, index) => {
if (params.status == "ready") {
uploadList[index].isShowJinDuTiao = true;
uploadList[index].isDisabled = true;
const interval = setInterval(() => {
if (uploadList[index].curPercentage >= 100) {
clearInterval(interval);
return;
}
if (uploadList[index].curPercentage < 99) {
uploadList[index].curPercentage += 1; //进度条进度
} else if (uploadList[index].curPercentage == 99) {
clearInterval(interval);
}
}, 30);
} else if (params.status == "success") {
uploadList[index].curPercentage = 100;
uploadList[index].isShowJinDuTiao = false;
uploadList[index].isDisabled = false;
}
};
- 如果文件上传数量限制为1时,如果想要二次上传文件去覆盖前一个文件
设置
limit和on-exceed可以在选中时自动替换上一个文件。
const handleFileExceed: UploadProps["onExceed"] =
(index) => (files, fileList) => {
uploadRefs.value[index]!.clearFiles();
const file = files[0] as UploadRawFile;
file.uid = genFileId();
uploadRefs.value[index]!.handleStart(file);
uploadRefs.value[index]!.submit();
};
- 文件上传后再移除,fileList对应移除文件
const handleFileUpload = async (params, index) => {
uploadList[index].fileList = [];
// fileType:
// doc 1; pdf 4; zip 5; mater 6; ga 7
let data: any = await uploadFile(params.file, params.data);
// 保存文件的 ID 到文件对象的 id 属性中
params.file.id = data.data.file.id;
// 添加到文件列表
uploadList[index].fileList.push(params.file);
};
const handleFileRemove = (file, index) => {
const fileIndex = uploadList[index].fileList.indexOf(file);
if (fileIndex !== -1) {
uploadList[index].fileList.splice(fileIndex, 1);
}
};
注: el-upload组件中的一些方法,如:on-change方法提供原有的参数:(uploadFile: UploadFile, uploadFiles: UploadFiles,若想要传递额外的参数,要怎么实现呢?
尝试了两种方法: 第一种 :on-change="handleFileChange(index)"
第二种: :on-change="(file) => handleFileChange(file, index)"
文件上传与移除,调用submit提交接口时,需要把fileIds传递给后台,因此用户要知道上传了哪些文件的fileIds,移除了哪些fileIds。 另外,在上传过程中会发现我只上传一个文件,但会在文件列表中出现两个一样的文件
看文档 on-change不止在添加文件的时候触发 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用,因此要改成只在添加文件时触发
:on-remove="handleFileRemove" :on-change="handleFileChange"
代码记录: el-upload组件
<el-upload
:http-request="uploadFile"
class="upload-demo"
v-model:file-list="fileList"
:on-progress="handleProgress"
:on-success="handleFileSuccess"
:before-remove="beforeFileRemove"
:on-remove="handleFileRemove"
:on-change="handleFileChange"
>
<el-button type="primary">Click to upload</el-button>
<template #tip>
<div class="el-upload__tip">
.doc, .zip, .docx, .pdf, .gif, .txt, .jpg, .jpeg, .png
files with a size less than 30mb.
</div>
</template>
</el-upload>
点击上传按钮
/**
* 自定义图片上传
* @param options
*/
async function uploadFile(options: UploadRequestOptions): Promise<any> {
const { data } = await discussionUpload(options.file);
// 保存文件的 ID 到文件对象的 id 属性中
options.file.id = data.content.fileId;
// 不要在这里处理fileId,否则文件移除时,获取到的fileId对应不上,除非没有移除文件功能
// ruleForm.fileId.push(data.content.fileId);
}
移除前事件
const beforeFileRemove = (uploadFile, uploadFiles) => {
return ElMessageBox.confirm(
`Cancel the transfer of ${uploadFile.name} ?`
).then(
() => true,
() => false
);
};
文件改变
const handleFileChange = (file, fileList) => {
// on-change只在添加文件触发: file.status === "ready"
if (file.status === "ready") {
fileList.vlaue?.push(file);
isFinished.value = false;
}
};
文件移除
const handleFileRemove = (file, fileList) => {
if (fileList.value && fileList.value.length > 0) {
fileList.value.splice(fileList.value.indexOf(file), 1);
}
};
点击submit提交数据
const submitForm = async (formEl: FormInstance | undefined) => {
ruleForm.aid = props.id;
ruleForm.discussionType = props.type;
ruleForm.fileId = [];
if (!formEl) return;
let targetFlag = fileList.value.every((item) => item.status === "success");
if (fileList.value.length > 0) {
if (!(targetFlag && isFinished.value)) {
return ElMessage({
type: "error",
message: "The file is uploading, please operate later",
});
}
}
// 重点,要在这里拼接fileId给后台
fileList.value &&
fileList.value.forEach((ele) => {
ruleForm.fileId.push(ele.raw.id);
});
await formEl.validate((valid, fields) => {
if (valid) {
saveDiscussion(ruleForm).then((res) => {
ElMessage({
message: res.message,
type: "success",
});
ruleFormRef.value.resetFields();
emit("dialogStatus", { show: false });
emit("uploadData");
});
} else {
console.log("error submit!", fields);
}
});
};