🚀Vue + Element Plus 实现自定义上传文件(自动收集 FormData 手动上传)
在日常前端开发中,我们常常需要通过表单上传多个文件,配合后端接口将其发送到服务器。本文将介绍如何在 Vue 3 + Element Plus 项目中,利用 el-upload 组件实现手动控制上传流程,包括文件选择、数据收集和上传请求。
📌 项目背景
使用 <el-upload> 的默认 action 参数虽然可以自动上传文件,但在实际业务中我们通常需要更灵活的控制,例如:
- 自定义上传接口逻辑(带认证信息、统一封装请求库等);
- 一次性提交多个文件(比如一组发票、凭证);
- 上传前对文件进行校验或处理;
- 上传后自动清理、刷新页面数据。
为此,我们使用 Element Plus 的 手动上传模式:禁用自动上传,监听 on-change 事件,并使用 axios 提交 FormData 数据。
🧱 实现步骤
1. 基础结构
我们使用 <el-upload> 搭配两个按钮:
- 一个按钮选择文件;
- 一个按钮手动上传。
<el-upload
multiple
action="" <!-- 禁用默认上传 -->
:show-file-list="false"
accept=".pdf,.gif,.jpg,.png"
:on-change="fileChange"
:auto-upload="false"
:file-list="fileList"
>
<el-button size="default" type="warning" class="ml10" :loading="isUpload" :disabled="isUpload">
<el-icon><ele-Upload /></el-icon>
选择文件
</el-button>
</el-upload>
<el-button size="default" type="warning" class="ml10" :loading="isUpload" :disabled="isUpload" @click="onUploadTest">
<el-icon><ele-Upload /></el-icon>
上传文件
</el-button>
2. 文件选择逻辑 fileChange
在用户每次选择文件后,我们通过 on-change 事件获取到完整的文件列表,保存在本地状态 fileList 中,用于后续上传处理。
const fileList = ref<UploadUserFile[]>([]);
const fileChange = (file: UploadFile, uploadFiles: UploadUserFile[]) => {
console.log('文件选择:', file, uploadFiles);
fileList.value = uploadFiles;
};
3. 上传逻辑 onUploadTest
点击“上传文件”按钮后,将 fileList 中的文件统一封装到 FormData,并通过接口请求发送至后端。
const isUpload = ref(false);
const onUploadTest = () => {
const formData = new FormData();
fileList.value.forEach(file => {
if (file.raw) {
formData.append('fileList', file.raw); // 后端要求字段名统一为 fileList
}
});
isUpload.value = true;
apiUploadTest(formData)
.then((res: any) => {
ElMessage.success(res.msg);
console.log('上传结果:', res);
initData(); // 可用于刷新数据列表
})
.catch(() => {
ElMessage.error('上传失败');
})
.finally(() => {
isUpload.value = false;
});
};
🔧 说明:
apiUploadTest是你封装的上传接口,例如基于axios.post实现。
✅ 技术要点总结
| 功能点 | 说明 |
|---|---|
:auto-upload="false" | 禁止 Element Plus 自动上传,改为手动触发 |
fileList | 手动管理用户选择的文件列表 |
file.raw | 通过 UploadUserFile.raw 获取真实 File 对象 |
FormData | 封装多个文件并传递给后端 |
axios | 自定义请求处理逻辑(更灵活可扩展) |
📌 常见问题 & 提示
- 多个文件字段名怎么办? 若后端要求数组格式:可使用
formData.append('fileList[]', file.raw); - 需要每个文件独立上传? 可以在
fileChange中逐个发请求; - 上传限制如大小、类型? 可结合
before-upload做校验; - UI 提示与 loading 状态? 用
isUpload控制按钮禁用与加载动画,提升用户体验。
📎 总结
使用 Element Plus 的 el-upload 组件配合 Vue 的响应式机制,我们可以轻松实现文件的手动上传控制,满足复杂业务场景下的定制需求。