vue3+ts el-upload多文件上传时 展示上传进度条

单文件上传
api代码

export const uploadFileHandle2 = (params: any,  url: string, onProgress:any) => {
	const formData = new window.FormData();
	params.forEach((file: any) => formData.append('files', file.raw));
    // 如果有自定义参数
    if (params.data) {
        Object.keys(params.data).forEach((key) => {
            const value = params.data[key];
            if (Array.isArray(value)) {
                value.forEach(item => {
                    formData.append(`${key}[]`, item);
                });
            } else {
                formData.append(key, value);
            }
        });
    }
    return request({
        url: url,//接口路径
        method: 'POST',
        data: formData,
        headers: {
            'Content-Type': 'multipart/form-data',
            ignoreCancelToken: true,
        },
		onUploadProgress: progressEvent => {
            const total = progressEvent.total as any;
            const current = progressEvent.loaded;
            const percentage = Math.round((current / total) * 100);
            if (onProgress) {
                onProgress(percentage); // 调用回调函数传递进度
            }
        },
    });
};

vue代码

<el-upload :before-upload="beforeUpload" v-model:file-list="fileList" :multiple="true" :show-file-list="false" :http-request="uploadUrlHandle">
	<el-button type="primary">上传文件</el-button>
</el-upload>
 <!-- 进度条弹窗 -->
		<el-dialog :modal="false"  v-model="showProgressBar" title="上传进度" width="30%" style="border-radius: 10px;position: fixed; bottom: 20px;right: 20px;" >
			<div v-if="uploadProgress !== null">
				<el-progress :percentage="uploadProgress"></el-progress>
			</div>
			<div v-else>
				<el-progress :percentage="0"></el-progress>
				上传失败
			</div>
		</el-dialog>

// 上传前的钩子
const beforeUpload = (file: File) => {
	fileList.value = [];
	// 控制只上传一次
	if (!hasUploaded.value) {
		hasUploaded.value = true;
		return true; // 允许上传
	}
	return false; // 阻止上传
};
const uploadProgress = ref(null);
const fileList = ref([]);
const hasUploaded = ref(false);
const onProgress = (progress: any) => {
	uploadProgress.value = progress; // 更新进度
};
const showProgressBar = ref(false);
const uploadUrlHandle = async (options: UploadRequestOptions, data: any) => {
	uploadProgress.value = null; // 重置进度
	const params = fileList.value.filter((item: any) => {
		return item.status === 'ready';
	});
	showProgressBar.value = true; // 显示进度条弹窗
	uploadPics(params, onProgress)
		.then(async (res) => {
			debugger;
			if (res.data.code == 200) {
				hasUploaded.value = false;
				res.data.result.forEach((item: any, indexA: any) => {});
			} else {
				hasUploaded.value = false;
			}
		})
		.catch((error) => {
			console.error('Upload failed:', error);
			hasUploaded.value = false;
			uploadProgress.value = null; // 重置进度
			fileList.value = [];
		});
};

多文件上传

### 使用 `el-upload` 组件实现文件切片上传 为了实现在 Vue 项目中的大文件切片上传,可以利用 Element UI 的 `el-upload` 组件并结合 File API 来处理文件分割与上传操作。下面是一个详细的解决方案以及相应的示例代码。 #### 方案概述 通过监听文件选择事件,在前端使用 JavaScript 的 File API 将选中的文件按照设定好的大小进行切割形成多个片段;之后再把这些片段逐个封装进 FormData 对象里发送给后台服务器保存起来[^1]。 对于每一个分片而言,都需要携一些额外的信息以便于后端能够识别该分片属于哪个完整的文件及其顺序位置等重要参数。通常情况下会包含如下字段: - 文件名 (`filename`) - 总分片数 (`totalChunks`) - 当前分片索引 (`chunkIndex`) - 分片数据本身 (`fileChunk`) 这些信息会被打包在一个表单对象内提交至服务端完成存储工作。 #### 示例代码 以下是基于上述描述的具体实现方式之一: ```vue <template> <div id="app"> <!-- el-upload 配置项 --> <el-upload class="upload-demo" drag :before-upload="handleBeforeUpload" action="" multiple> <i class="el-icon-upload"></i> <div class="el-upload__text">将文件拖到此处,或点击<em>上传</em></div> </el-upload> </div> </template> <script> export default { methods: { handleBeforeUpload(file) { const CHUNK_SIZE = 1 * 1024 * 1024; // 设置每一片为1MB let chunks = Math.ceil(file.size / CHUNK_SIZE); // 计算总共需要多少片 for (let i = 0; i < chunks; ++i) { let start = i * CHUNK_SIZE; let end = ((i + 1) * CHUNK_SIZE >= file.size ? file.size : (i + 1) * CHUNK_SIZE); this.uploadFileSlice(i, chunks, file.slice(start, end), file.name); } return false; // 返回false阻止默认行为 }, uploadFileSlice(index, total, blob, filename){ var formData = new FormData(); formData.append(&#39;file&#39;, blob); formData.append(&#39;index&#39;, index); formData.append(&#39;total&#39;, total); formData.append(&#39;name&#39;, filename); axios.post(&#39;/api/upload-slice&#39;, formData).then(response => { console.log(`第${index}片已成功上传`); }).catch(error => { console.error(`第${index}片上传失败`, error); }); } } } </script> ``` 此段代码展示了如何配置 `el-upload` 并定义了一个自定义方法来拦截文件上传过程之前的操作——即先做文件的预处理(比如这里就是指按需切割)。每当有新的文件被加入队列就会触发这个函数执行一系列动作直到所有的部分都被妥善安置好为止。 值得注意的是这里的 `action=""` 属性为空字符串是因为实际的数据传递是由内部调用 AJAX 请求完成而不是依赖于 `<form>` 表单的传统提交机制。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值