这里要实现这样一个功能,就是批量上传图片的功能,在上传的时候,选择要上传的文件夹,这个组件会自动取读取这个文件夹中所有的文件,并挨个进行上传,我们需要再上传的时候添加个过滤条件,只有符合我们规定的文件才会调用接口完成真正的上传功能。这里面还有个直接上传到七牛云的
组件代码:
<a-upload-draggername="file":fileList="filesList"directory:show-upload-list="false":auto-upload="false"@change="handleFiles"><div class="upload-area"><upload-one theme="filled" size="24" fill="#383838" :strokeWidth="3"/><div class="text">上传文件夹</div></div>
</a-upload-dragger>
/**
*directory:允许上传文件夹
*show-upload-list:是否显示上传的文件列表
*auto-upload:是否开启自动上传
*change:文件状态改变的回调
**/
/**
*change
*文件状态改变的回调,返回为:
*{
* file: { /* ... */ },
* fileList: [ /* ... */ ],当前的文件列表。
* event: { /* ... */ },
*}
**/
这个具体上传的方法,用了一个防抖,主要是因为,这个 <a-upload-dragger>组件只要查到一个文件就会调用一次,不是等加载完所有的文件后,才取一次性调用完成上传。但其实我们在第一次就能拿到文件夹中所有的文件,所以需要加一个防抖,防止重复上传。
async function handleFiles({ fileList }) {clearTimeout(debounceTimeout.value);loading.value = true;debounceTimeout.value = setTimeout(async () => {// console.log('fileList', fileList);const files = Array.isArray(fileList) ? fileList : [fileList];const uploadPromises = files.map(item => {// 进行规则校验if (validateFile(item)) {return uploadFileFn(item.originFileObj);}// return Promise.reject(new Error(`文件 ${item.name} 不符合上传条件`));return Promise.resolve();});try {// 等待所有符合条件的文件上传完成const re = await Promise.all(uploadPromises);const successCount = re.filter(it => it && it.data.success).length;const errorCount = re.filter(it => it && !it.data.success).map(item => item.data.message);is.value = true;backData.value = {successCount,errorCount: errorCount.length,errorContent: errorCount,};} catch (error) {// message.error('文件部分不符合上传条件');} finally {loading.value = false;emits('importSuccess');// closeDialog();}}, 300); // 300 毫秒的防抖延迟
}
自定义校验,检查文件是否符合上传的规则。
function validateFile(file) {// 自定义规则校验,返回 true 或 falseconst allowedTypes = ['image/jpeg', 'image/png'];return allowedTypes.includes(file.type);
}
自定义文件上传方法:这里用到的是直接上传到七牛云,但这个方法没写全,上传之前,还需要拿到七牛云的token,这个需要自己写。
async function uploadFileFn(file) {try {const tokenData = await uploadFileGetToken({file_upload_business_type: 'product_library',});if (!tokenData) {throw new Error('获取上传 token 失败');}const fileFormData = new FormData();fileFormData.set('file', file);fileFormData.set('key', `${tokenData.data.key}${file.name.slice(file.name.lastIndexOf('.') + 1)}`);fileFormData.set('token', tokenData.data.token);fileFormData.set('business_type', 'attachment');const res = await axios.post('https://up.qiniup.com/', fileFormData, {headers: {Authorization: `UpToken ${tokenData.data.token}`,'Content-Type': 'multipart/form-data',},});if (res.data.success === false) {throw new Error(res.data.msg || '上传失败');}const backUrlItem = `${tokenData.data.domain}${res.data.key}`;const uploadImgObj = {cover_image: backUrlItem,name: file.name.replace(/\.[^/.]+$/, ''),};return Promise.resolve();} catch (error) {// console.error('上传文件时发生错误:', error);return Promise.reject(error); // 返回错误}
}