ElementUI提交图片表单
后端接口
后端接口支持Form表单提交,其中title、url、description、sort为必填,logo为选填
logo必须接收binary二进制image文件,不支持string或者base64
前端实现
表单代码
<el-form :model="currentItem" :rules="formRule" ref="submitRef" label-width="80px" enctype="multipart/form-data">
<el-form-item label="标题" prop="title">
<el-input v-model="currentItem.title"/>
</el-form-item>
<el-form-item label="描述" prop="description">
<el-input v-model="currentItem.description" type="textarea"/>
</el-form-item>
<el-form-item label="链接" prop="url">
<el-input v-model="currentItem.url"/>
</el-form-item>
<el-form-item label="分类" prop="category">
<el-select v-model="currentItem.category" placeholder="请选择分类">
<el-option v-for="category in state.category" :key="category.id" :label="category.title"
:value="category.id"/>
</el-select>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input-number v-model="currentItem.sort"/>
</el-form-item>
<el-form-item label="Logo">
<!-- 上传组件 -->
<el-upload
action=""
class="avatar-uploader"
:show-file-list="false"
:before-upload="handleBeforeUpload"
>
<img v-if="currentItem.logo" :src="currentItem.logo" class="avatar"/>
<el-icon v-else class="avatar-uploader-icon">
<plus/>
</el-icon>
</el-upload>
</el-form-item>
</el-form>
const currentItem = reactive({
id: null,
category_cn: "",
title: "",
url: "",
description: "",
sort: 0,
logo: null,
category: 0
});
const handleAdd = () => {
Object.assign(currentItem, {
id: null,
category_cn: '',
title: '',
url: '',
description: '',
sort: 1,
logo: null,
category: null,
logoFile: null,
})
dialogVisible.value = true
}
function handleBeforeUpload(file) {
// 构造图片本地链接
var windowURL = window.URL || window.webkitURL;
currentItem.logo = windowURL.createObjectURL(file);
// 创建文件对象
currentItem.logoFile = file
return false;
}
function handleSubmit() {
proxy.$refs.submitRef.validate((valid) => {
if (valid) {
// 构造提交表单
const formData = new FormData();
formData.append('title', currentItem.title);
formData.append('url', currentItem.url);
formData.append('description', currentItem.description);
formData.append('sort', currentItem.sort);
formData.append('category', currentItem.category);
// 非必填项
if (currentItem.logoFile) {
formData.append('logo', currentItem.logoFile);
}
if (currentItem.id === null) {
// 添加数据
proxy.$axios.post("v1/site/", formData).then((res) => {
state.sites.push(res.data);
dialogVisible.value = false;
ElMessage.success("添加成功")
});
} else {
// 更新数据
proxy.$axios.patch(`v1/site/${currentItem.id}/`, formData).then((res) => {
const index = state.sites.findIndex((site) => site.id === currentItem.id);
state.sites.splice(index, 1, res.data);
dialogVisible.value = false;
ElMessage.success("更新成功")
});
}
} else {
return false;
}
})
}
首先构造一个空字典currentItem用来初始化提交表单
然后在提交表单中配置el-upload组件
el-upload默认是上传文件后自动提交到action地址,这种方法是图片和表单分开提交,由于我们后端接口要求一起提交,所以我们需要关闭el-upload的默认上传动作
将action地址留空,配置before-upload,上传文件后触发handleBeforeUpload
handleBeforeUpload接收file对象,先构造出file对象的本地路径,然后赋值给currentItem.logo,用来在网页上临时显示图片
然后将file对象直接赋值给currentItem.logoFile,稍候用来提交到后端
return false关闭el-upload的自动上传动作
handleSubmit用来提交表单,提交表单前,构造一个formData对象,然后将currentItem字典分别传入formData对象
由于logo是非必填项,需要判断一下currentItem.logoFile是否为空,如果不为空再传入formData
最后将包含图片文件的formData直接提交到后端即可