ant design vue 上传文件组件
<a-upload-dragger
v-model:fileList="fileList"
:accept="accept"
:beforeUpload="beforeUploadFile"
class="upload-btn"
:headers="headers"
multiple
@change="handleChange"
>
<button v-if="!showUploadFiles" class="submitbtn">点击上传</button>
<button v-else class="submitbtn">继续上传</button>
</a-upload-dragger>
<div v-else class="file-list">
<div class="file-item" v-for="(item,index) in uploadFileList" :key="index">
<span class="fileName">{{ item.file?.name}}</span>
<span class="fileSize">{{ sizeCompt(item.file?.size) || 0 }}</span>
<span :class="{'error-statue':item.status=='error','loading-status':item.status=='uploading'}">{{ item.status=='error'?'上传失败,请重试' : item.status=='uploading'?'上传中':''}}</span>
<div class="svg" v-show="item.status=='uploading'">
<img src="@/assets/images/uploading.gif" alt="">
</div>
<div class="svg">
<svg xmlns="http://www.w3.org/2000/svg" v-if="item.status=='done'" viewBox="0 0 18 18" fill="none">
<image href="@/assets/images/svg/uploadSuccess.svg" x="0" y="0"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" v-else-if="item.status=='error'" viewBox="0 0 18 18" fill="none" @click="reupload(item)">
<image href="@/assets/images/svg/reupload.svg" x="0" y="0"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" v-else viewBox="0 0 18 18" fill="none" @click="cancelUpload(item)">
<image href="@/assets/images/svg/cancelUpload.svg" x="0" y="0"/>
</svg>
</div>
</div>
// 上传文件部分
const accept = ref(
".ppt,.pps,.jpeg,.jfif, .pot, .ppa,.pptx,.ppsx,.potx,.doc,.docx,.docm,.dot,.docx,.xlsx,.xls,.csv,.xlsb,.xltx,.xltm,.xlam,.mp4,.flv,.f4v,.webm,.mpeg,.mov,.wmv,.pdf,.txt,.zip,.rar,.7z,.tar,.gz,.tiff,.png,.psd,.raw,.svg,.eps,.jpg,.raw,.ai,.gif"
);
//文件列表
const fileList = ref([]);
//请求头
const headers = {
token: ls.get("token"),
"content-type": "multipart/form-data",
};
上传文件前操作
// 上传文件之前的钩子,参数为上传的文件
const beforeUploadFile = (file, fileLists) => {
console.log("拿到的文件列表", file, fileList.value);
//判断文件大小是否超过剩余空间
// if(file.size>diskData.value.free){
// message.warning('您的存储空间不足')
// return false
// }
// 限制文件类型
// const fileNames = file.name.split('.')
// const fileType = fileNames[fileNames.length - 1].toLocaleLowerCase()
// const extList = ['jpg','jpeg', 'png', 'gif','ppt','word','excel','mp4','pdf','txt','doc','docx','zip','exe','bat','vbs']
// if (!extList.find((item) => item == fileType)) {
// this_.$message.error('不能上传.'+fileType+'类型的文件!')
// return false
// }
// console.log(888)
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
uploadFiles(fileLists);
}, 500);
return false;
};
上传文件列表时:使用防抖避免重复调用上传函数
并发请求
// 并发请求
const concurrency = async (promiseList, max) => {
let index = 0;
const results = new Array(promiseList.length);
const executing = [];
const runCurrency = async () => {
if (index == promiseList.length) {
return;
}
const currencyIndex = index++;
const currency = promiseList[currencyIndex];
const p = currency()
.then((result) => {
results[currencyIndex] = result;
executing.splice(executing.indexOf(p), 1);
})
.catch((error) => {
results[currencyIndex] = error;
executing.splice(executing.indexOf(p), 1);
});
executing.push(p);
let r = Promise.resolve;
if (executing.length >= max) {
r = Promise.race(executing);
}
await r;
await runCurrency();
};
await runCurrency();
await Promise.all(executing);
getDiskFileList();
return results;
};
详细解析
index
:用于跟踪当前处理的 promise 索引。results
:存储每个 promise 的结果。executing
:用于跟踪当前正在执行的 promise。
runCurrency
函数
- 如果所有 promise 都已执行完毕,则返回。
- 否则,获取当前的 promise,并将其执行。
- 使用
Promise.race
控制并发,确保同时只执行max
个 promise。 - 递归调用
runCurrency
以处理下一个 promise。
上传函数
// 上传函数
const uploadFiles = async (fileLists) => {
fileList.value = fileLists.map((item, index) => {
const { uid } = item;
return {
uid,
file: item,
status: "init",
};
});
showUploadFiles.value = true;
uploadFileList.value.push(...fileList.value);
console.log(2345, uploadFileList.value, fileList.value);
const promitList = uploadFileList.value.map((item) => {
return async () => {
// 限制文件类型
const fileNames = item.file?.name.split(".");
const fileType =
fileNames[fileNames.length - 1].toLocaleLowerCase();
const extList = [
"tiff",
"jpeg",
"jfif",
"png",
"psd",
"raw",
"svg",
"eps",
"jpg",
"raw",
"ai",
"gif",
"ppt",
"pps",
"pot",
"ppa",
"pptx",
"ppsx",
"potx",
"doc",
"docx",
"docm",
"dot",
"dotx",
"xlsx",
"xls",
"csv",
"xlsb",
"xltx",
"xltm",
"xlam",
"mp4",
"flv",
"f4v",
"webm",
"mpeg",
"mov",
"wmv",
"mp3",
"wma",
"wav",
"ape",
"flac",
"ogg",
"aac",
"pdf",
"txt",
"zip",
"rar",
"7z",
"tar",
"gz",
];
if (!extList.find((item) => item == fileType)) {
item.status = "wrong";
return false;
}
const formData = new FormData();
formData.append("files", item.file);
item.status = "uploading";
console.log(formData, item.file);
try {
await requploadFiles(window, item.uid, formData);
item.status = "done";
diskStore.getGroup();
getDiskFileList();
diskStore.getDiskMemory();
} catch (error) {
message.error(error.message);
item.status = "error";
}
// uploadFileList.value=uploadFileList.value.map((i)=>{
// if(i.uid==item.uid){
// i.status=item.status
// }
// return item
// })
// console.log('after',uploadFileList.value)
// uploadFileList.value=uploadFileList.value.filter((fileItem)=>fileItem.uid!=item.uid)
// console.log('before',uploadFileList.value)
};
});
concurrency(promitList, 6);
};
详细解析
fileList.value
:将传入的文件列表映射为具有uid
、file
和status
属性的对象数组。showUploadFiles.value
:显示上传文件的状态。promitList
:存储每个文件的上传逻辑,返回一个 async 函数。
文件类型检查和上传
- 检查文件类型是否在允许的扩展名列表中。
- 使用
FormData
构造上传请求的主体。 - 根据上传结果更新文件的状态,并在上传成功或失败时进行相应的处理
重新上传
// 重新上传
const reupload = async (item) => {
console.log("reupload");
const formData = new FormData();
formData.append("files", item.file);
uploadFileList.value.map((i) => {
if (i.uid == item.uid) {
i.status = "uploading";
}
});
try {
await requploadFiles(window, item.uid, formData);
uploadFileList.value.map((i) => {
if (i.uid == item.uid) {
i.status = "done";
}
});
diskStore.getGroup();
getDiskFileList();
diskStore.getDiskMemory();
} catch (error) {
message.error(error.message);
uploadFileList.value.map((i) => {
if (i.uid == item.uid) {
i.status = "error";
}
});
}
};
取消上传
// 取消上传
const cancelUpload = (item) => {
console.log("cancle");
if (typeof window?.[item.uid] === "function") {
window?.[item.uid]("请求中断");
}
};
文件状态回调
// 文件状态改变的回调——上传中、完成、失败都会调用这个函数。
const handleChange = (info) => {
if (info.file.status !== "uploading") {
console.log(info.file, info.fileList);
}
if (info.file.status === "done") {
message.success(`${info.file.name} file uploaded successfully`);
// diskStore.getDiskMemory()
} else if (info.file.status === "error") {
message.error(`${info.file.name} file upload failed.`);
}
};
标签:文件,const,uid,自定义,value,item,file,上传
From: https://blog.csdn.net/m0_56772756/article/details/141868348