今天在使用vue-element-admin框架撸后台的过程中遇到了单表单中上传多文件的问题。在此做下记录。
后端有一个模型上传的接口,前端需要通过post方法将模型文件、模型封面以及其他额外信息提交给后端,其中模型的文件和封面是文件类型,其他信息是string类型。
由于element的upload组件是单文件post上传的形式,没法使用它的el-upload组件在一个表单中提交多个文件给后端。
这里选择使用默认的表单提交功能来实现,html代码如下:
<el-form ref="dataForm" :rules="rules" :model="temp" label-position="left" label-width="80px" style="width: 400px; margin-left:50px;">
<el-form-item label="模型名字" prop="name" >
<el-input v-model="temp.name"/>
</el-form-item>
<el-form-item label="模型描述" prop="description">
<el-input v-model="temp.description"/>
</el-form-item>
<el-form-item label="模型封面" prop="cover">
<el-input v-model="temp.cover" type="file" @change="handleFileChange($event, 'cover')" />
</el-form-item>
<el-form-item label="模型" prop="model">
<el-input v-model="temp.model" type="file" @change="handleFileChange($event, 'model')" />
</el-form-item>
</el-form>
然后添加handleFileChange
方法:
handleFileChange (event, type) {
this.temp[type] = event.target.files[0]
}
这个方法的本意是是拿到event
对象之后,将event
对象中的文件赋值给待提交的表单对象temp
,但是传进来的event
参数不是一个对象,而是一个路径形式的字符串:
这里是
el-input
这个组件的原因导致的,有两种解决办法,一种是给这两个el-input
各加一个id
属性,然后在handleFileChange
方法中通过getElementById
来获取对象的files
属性。不过这种方法在代码上相对就显得有些臃肿。于是我选择使用原生的input
标签来接受event
对象,修改过之后的html代码如下:
<el-form-item label="模型封面" prop="cover">
<input type="file" @change="handleFileChange($event, 'cover')">
</el-form-item>
<el-form-item label="模型" prop="model">
<input type="file" @change="handleFileChange($event, 'model')" >
</el-form-item>
接下来实现createModel
方法:
createModel () {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
uploadModel(this.temp)
.then(() => {
this.dialogFormVisible = false
this.$notify({
title: '成功',
message: '上传成功',
type: 'success',
duration: 2000
})
this.getList()
this.resetTemp()
})
}
})
},
上面代码中的uploadModel
方法是经过封装之后的axios
请求,源码如下:
const uploadModel = function (formData) {
return request({
url: '/api/model',
method: 'post',
headers: {
'Content-Type': 'multipart/form-data'
},
data: formData,
transformRequest: [function (data, headers) {
const formData = new FormData()
for (const key of Object.keys(data)) {
formData.append(key, data[key])
}
return formData
}]
})
}
这里首先需要注意的是将Content-Type
请求头的值改为multipart/form-data
,表示表单形式是文件上传。其次要注意post的数据需要是FormData
类型,不能是普通的对象,这里通过transformRequest
方法,将参数formData
中的属性复制到新建的FormData
对象上。
网友评论