Element UI 上传器 <el

编程入门 行业动态 更新时间:2024-10-21 10:04:33

笔者在项目中有如下需求:使用多个 el-upload 手动上传文件,最后一次性提交。后台要求提交的文件格式是 binary 即二进制形式,实现过程中出现了文件数据以对象方式提交给后端导致报错。

01 Bug 描述

笔者在使用 Vue + Element UI 进行前端开发时遇到多文件上传的需求,我使用 Element UI 的 el-upload 上传器组件实现这一功能,使用如下图所示的官方用例进行开发

基于上述 手动上传 用例实现多个文件上传时,后端响应结果为 上传文件为空,即文件没有正确发送给后端,如下所示:

02 手动上传多个文件实现过程

首先回顾手动上传多个文件实现过程,主要分为如下三步:

HTML 页面中引入 el-upload 组件并设置属性JS 中监听文件上传事件并作出响应操作使用 Axios 将文件发送给后端处理

2.1 引入 el-upload 组件

el-upload 组件实现了用户点击上传按钮从本地上传文件,这些文件构成的上传文件列表 file-list 将被上传到组件的必选参数 action 指定的地址中。

除了这两个基础参数,该组件还可以通过设置 limiton-exceed 来限制上传文件的个数和定义超出限制时的行为。 更多其他属性设置可以参考官方文档 Upload 上传

<template><el-uploadref="upload"action="jsonplaceholder.typicode./posts/":auto-upload="false":on-change="handleChange"multiple:limit="3":on-exceed="handleExceed":file-list="fileList"><el-button size="small" type="primary" @click="createTask()">上传</el-button><template #tip><div class="el-upload__tip">jpg/png files with a size less than 500kb</div></template></el-upload>
</template>

2.2 监听文件上传事件

笔者的项目中,多个文件是作为向后端提交的表单的一部分,所以不直接使用 action 属性指定的上传地址,并将 auto-upload 属性设置为 false 实现手动上传。

除此之外,还需要定义 on-change 属性,该属性是监听文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用。我们使用该属性实现,动态获取文件上传组件的上传文件列表,并将文件作为提交表单的一部分。相关内容的 JS 代码如下:

<script>
import { addTask } from '@/api/task'
export default {data() {return {// 提交的表单taskForm: {content: null,title: null,attachments: [] // 要向后端传输的多个文件}}},methods: {// 监听文件状态handleChange(file, fileList) {// 将上传文件列表中的所有文件拷贝到 taskForm.attachments 中fileList.forEach(file => {this.taskForm.attachments.push(file)})},// 监听文件数目上限handleExceed(files, fileList) {this.$message.warning(`The limit is 3, you selected ${files.length} files this time, add up to ${files.length + fileList.length} totally`)},// 提交表单表单由三个部分构成 content title 和由多个文件构成的 attachmentscreateTask() {console.log('this task', this.taskForm)this.$refs['taskForm'].validate((valid) => {if (valid) {addTask(this.taskForm).then((response) => {this.$refs.upload.clearFiles()})}})}}
}
</script>

2.3 Axios 向后端传送文件

最后使用 @api/task 中定义的 axios 后端接口 addTask 传送数据,需要注意的是 2.2 中的 taskForm 是 JSON 格式的数据,如果后端处理是接收 FormData 格式的数据需要进行转换。笔者的后端要求接收的是 FormData 格式数据,所以使用 transformRequest 方法将其转换。

export function addTask(data) {return request({method: 'post',url: '/task',headers: {'Content-Type': 'multipart/form-data'},// 将 json 格式的 data 转换成 formDatatransformRequest: [function(data) {const formData = new FormData()for (var key in data) {formData.append(String(key), data[key])}}],data})
}

03 追溯 Bug

梳理了实现过程之后,我开始在每个环节中筛查 Bug。

首先检查了 HTML 中 el-upload 属性是否定义正确,主要是将 auto-upload 属性设置为 false 实现手动上传,定义 on-change 属性获取上传文件列表。

然后检查 on-change 属性的 handleChange() 方法是否正确获取了 el-upload 组件的上传文件列表 file-listhandleChange() 方法添加输出语句如下:

	handleChange(file, fileList) {fileList.forEach(file => {this.taskForm.attachments.push(file)})console.log('attachments', this.taskForm.attachments)},

输出如下,这里我们可以发现第一个 Bug:笔者项目的后端要求接收的文件类型是二进制格式的,而 attachments 中存放的是一个文件对象包含name, size, uid 等额外字段,而我们仅需要其中的二进制数据 raw ,所以仍然报错。

最后,检查 @api/task 中定义的 axios 后端接口 addTask ,虽然修改上述 Bug 之后 attachments 中都是二进制文件,但基于 2.3 节代码实现的 addTask 传送给后端的 attachments 是一个列表,而非二进制数据,所以仍然报错,如下图所示:

04 解决 Bug

发现上述 Bug 后,我们逐一进行解决,首先正确获取 el-upload 组件中 filelist 文件列表中二进制文件数据,仅获取 file.raw 数据即可,修改如下:

	handleChange(file, fileList) {fileList.forEach(file => {this.taskForm.attachments.push(file.raw)})},

接着我们需要修改 @api/task 中定义的 axios 后端接口 addTask 实现方式,如果直接将二进制文件数据构成的 attachments 作为 formData 的一个键值对传送给后端会被视为一个列表使得后端无法正确解析。为此,我们单独处理 attachments 的 formData 转换,将二进制文件数据分别封装如下:

export function addTask(data) {return request({method: 'post',url: '/task',headers: {'Content-Type': 'multipart/form-data'},transformRequest: [function(data) {const formData = new FormData()for (var key in data) {// 单独处理二进制文件数据 attachmentsif (key === 'attachments') {continue}formData.append(String(key), data[key])}// 单独处理二进制文件数据 attachmentsfor (var file of data['attachments']) {formData.append('attachments', file)}return formData}],data})
}

修改上述 Bug 之后再次测试结果如下,可以看到文件通过二进制的方式使用同一个 key attachments 传给后端


响应成功如下所示:

参考资料

Element UI 官方文档 Upload 上传

el-upload控件一次接口请求上传多个文件

更多推荐

上传,Element,UI,el

本文发布于:2023-05-29 23:08:34,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/355073.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:上传   Element   UI   el

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!