需求:有一个这样的页面,第一个输入框可以上传文件,然后可以输入版本号、版本说明等信息
预期结果:点击确定可以将文件和form表单数据(版本号、说明)等信息一起提交。
vue代码:(核心代码)
<el-form
ref="formRef"
:model="model"
:rules="rules"
label-width="140px"
size="small"
v-loading="loading">
<el-form-item label="文件上传" prop="fileName">
<el-input type="text" id="fileName" v-model="model.fileName" placeholder="请选择exe或者zip格式的文件" />
<el-upload
ref="uploadFile"
class="upload"
action=""
style="display: inline-block;"
:before-upload="beforeUpload"
accept=".exe,.zip">
<el-button size="small" type="text">点击上传</el-button>
</el-upload>
</el-form-item>
<el-form-item label="版本号" prop="version">
<el-input v-model="model.version" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="small" @click="handleClose" >取消</el-button>
<el-button
size="small"
type="primary"
@click="submit()"
:loading="loading">确定</el-button>
</div>
提交流程:
-
关闭文件的自动提交。
-
自定义提交方法,在其中把inputstream中的文件取出来
-
将数据对象转为表单数据 !!将data转换为form-data,使用Formdata保存上传的文件,同时保存后台接口需要的参数
-
发起axios请求提交表单
核心就是阻断组件自己的提交流程,把数据取出加入到自己的formdata中一并提交
data数据:
model: {
fileName: '',
description: '',
version: '',
file: ''
},
//钩子函数,阻止文件自动上传
beforeUpload (file) {
//file是选中的文件
this.model.file = file
this.model.fileName = file.name
return false // 阻止组件自动上传,自己掉上传接口!!重要哦!!!!
},
//点击确定的提交事件
submit () {
//手动调用上传
this.$refs.uploadFile.submit()
//新建form表单 Formdata保存上传的文件,同时保存后台接口需要的参数
const formData = new FormData()
//将data转换为form-data
Object.keys(this.model)
.forEach(key => {
if (this.model[key] instanceof Array) {
// 如果是数组就循环加入表单,key保持相同即可,这就是表单的数组
this.model[key].forEach(item => {
formData.append(key, item)
})
} else {
// 如果不是数组就直接追加进去
formData.append(key, this.model[key])
}
})
this.$refs.formRef.validate((valid) => {
if (valid) {
this.loading = true
// 调用api提交
// 直接调用封装好的函数不生效,使用原生api
Axios({
method: 'post',
url: 'xxx',
headers: {
Authorization: store.state.user.token
},
data: formData //formdata对象作为参数
})
.then((res) => {
if (res.data.status === 200) {
this.loading = false
this.handleClose()
this.$message.success('新增成功!')
this.$emit('refreshData')
} else {
this.loading = false
this.$message.error(res.data.message)
}
})
.catch((err) => {
this.loading = false
this.$message.error(err)
})
}
})
}
使用原生api的原因:
- 使用包装好的request方法,发现在使用data传值的时候,file的内容总是为空
- 所以使用原生api的方式进行请求