element-ui 中upload组件与表单组件的结合使用
背景
有的时候我们需要在表单中携带一些上传的附件传给服务器
搭建基本表单结构
<template>
<div>
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm"
>
<el-form-item label="活动名称" prop="name">
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item label="活动区域" prop="region">
<el-select v-model="ruleForm.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="上传附件" prop="attachment" class="upload-item">
<el-upload
ref="upload"
action=""
:on-remove="handleRemove"
:file-list="fileList"
:auto-upload="false"
>
<el-button slot="trigger" size="small" type="primary"
>选取文件</el-button
>
<div slot="tip" class="el-upload__tip">
只能上传jpg/png文件,且不超过500kb
</div>
</el-upload>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')"
>立即创建</el-button
>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
ruleForm: {
name: '',
region: '',
attachment: '',
},
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'blur' },
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' },
],
region: [
{ required: true, message: '请选择活动区域', trigger: 'change' },
],
attachment: [
{ required: true, message: '请上传附件', trigger: 'blur' },
],
},
fileList: [],
}
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
alert('submit!')
} else {
console.log('error submit!!')
return false
}
})
},
resetForm(formName) {
this.$refs[formName].resetFields()
},
handleRemove(file, fileList) {
console.log(file, fileList)
},
},
}
</script>
<style scoped>
</style>
问题1:upload的label不垂直居中
添加如下样式即可解决。
.upload-item {
display: flex;
}
/deep/ .upload-item .el-form-item__label {
display: flex;
justify-content: center;
align-items: center;
background-color: orange;
}
/deep/ .upload-item .el-form-item__content {
margin-left: 0 !important;
}
效果如下:
问题2:文件已经上传,但是表单组件校验不通过
问题效果:
解决办法:使用表单组件中的自定义规则
data() {
var validateAttachment = (rule, value, callback) => {
if (value == '') {
return callback(new Error('上传的附件不能为空'))
} else {
console.log('有上传附件')
callback()
}
}
return {
ruleForm: {
name: '',
region: '',
attachment: [],
},
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'blur' },
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' },
],
region: [
{ required: true, message: '请选择活动区域', trigger: 'change' },
],
attachment: [{ validator: validateAttachment, trigger: 'change' }],
},
}
优化
需求一:上传文件后,当移除时提示"附件必填"错误的消息;
需求二:表单中存在多个上传文件,为某个指定的表单项做单独的设置
如何获取到对应的表单项?
<el-upload
:on-remove="
(file, fileList) => {
handleRemove('attachment', file, fileList)
}
"
:file-list="ruleForm.attachment"
:auto-upload="false"
:on-change="
(file, fileList) => {
handleUploadChange('attachment', file, fileList)
}
"
>
完整代码
<template>
<div>
{{ ruleForm }}
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm"
>
<el-form-item label="活动名称" prop="name">
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item label="活动区域" prop="region">
<el-select v-model="ruleForm.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item
label="上传附件"
prop="attachment"
required
class="upload-item"
>
<el-upload
ref="upload"
action=""
:on-remove="
(file, fileList) => {
handleRemove('attachment', file, fileList)
}
"
:file-list="ruleForm.attachment"
:auto-upload="false"
:on-change="
(file, fileList) => {
handleUploadChange('attachment', file, fileList)
}
"
>
<el-button slot="trigger" size="small" type="primary"
>选取文件</el-button
>
<div slot="tip" class="el-upload__tip">
只能上传jpg/png文件,且不超过500kb
</div>
</el-upload>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')"
>立即创建</el-button
>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data() {
var validateAttachment = (rule, value, callback) => {
if (value == '') {
return callback(new Error('上传的附件不能为空'))
} else {
console.log('有上传附件')
callback()
}
}
return {
ruleForm: {
name: '',
region: '',
attachment: [],
},
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'blur' },
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' },
],
region: [
{ required: true, message: '请选择活动区域', trigger: 'change' },
],
attachment: [{ validator: validateAttachment, trigger: 'change' }],
},
}
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
alert('submit!')
} else {
console.log('error submit!!')
return false
}
})
},
resetForm(formName) {
this.$refs[formName].resetFields()
},
handleRemove(field, file, fileList) {
// console.log(file, fileList)
this.ruleForm[field] = []
this.$refs.ruleForm.validateField('attachment')
},
handleUploadChange(field, file, fileList) {
this.ruleForm[field].push(file)
},
},
}
</script>
<style scoped>
/* 解决表单中嵌入上传组件时label不居中的问题 */
.upload-item {
display: flex;
}
/deep/ .upload-item .el-form-item__label {
display: flex;
justify-content: center;
align-items: center;
background-color: orange;
}
/deep/ .upload-item .el-form-item__content {
margin-left: 0 !important;
}
</style>
效果如下: