最终实现需求如下图:
form表单内容与重点人员图片同时上传且图片为必填项
分析弹框页需要解决的问题有:
2、新增和编辑用同一个组件如何处理数据
3、图片需要和信息一起传递(即不允许自动上传)
4、图片必填的验证问题
针对上述问题作出方案:
1、el-form的表单验证需要注意几个地方:
a:el-form-item的prop值需要和表单标签的v-model值保持一致
例如:
<el-form-item label="姓名:" prop="name"> <el-input v-model="addKeyPersonForm.name" placeholder="请输入姓名"></el-input> </el-form-item>
b:验证规则有直接用element官网提供的也有自定义的
例如:其中checkNumber就是自定义的验证数字的正则
rules: { // 表单验证 name: [ { required: true, message: '必填项', trigger: 'blur' } ], age: [ { required: true, message: '必填项', trigger: 'blur' }, { validator: checkNumber, trigger: 'blur' } ], sex: [ { required: true, message: '必填项', trigger: ['blur', 'change'] } ], nationlity: [ { required: true, message: '必填项', trigger: ['blur', 'change'] } ], userType: [ { required: true, message: '必填项', trigger: ['blur', 'change'] } ], idCard: [ { required: true, message: '必填项', trigger: 'blur' }, { validator: checkIdCard, trigger: 'blur' } ], registered: [ { required: true, type: 'array', message: '必填项', trigger: ['blur', 'change'] } ], registeredDetails: [ { required: true, message: '必填项', trigger: 'blur' } ], domicile: [ { required: true, type: 'array', message: '必填项', trigger: ['blur', 'change'] } ], domicileDetails: [ { required: true, message: '必填项', trigger: 'blur' } ], file: [ { required: true, message: '请上传图片' } ], plateNumber: [ { validator: checkPlateNum, trigger: 'change' } ] }
2、新增和编辑问题需要我们在打开组件的时候传递两个值
props: { dialogType: { //是新增还是编辑,用于判断 type: String }, keypersonList: { //表单的原始值 type: Object } }
3、图片和form表单内容一起上传
首先我们需要阻止图片的自动上传让它等到我们点击保存按钮的时候再一起传给后台
我们看这段代码就是图片上传组件
<el-upload :style="{backgroundImage:'url(' + dialogImageUrl + ')', backgroundRepeat:'no-repeat', backgroundPosition:'center center', backgroundSize: 'contain'}" ref="uploadxls" action="aaa" ::limit="1" :show-file-list="false" :on-change="handlePictureCardPreview" :before-upload="beforeupload" accept="image/png,image/gif,image/jpg,image/jpeg"> <i v-show="!dialogImageUrl"></i> <div v-show="!dialogImageUrl" slot="tip">上传照片</div> </el-upload>
action我们随便填一个就好,重点是这一句:before-upload="beforeupload"在图片上传之前执行beforeupload方法在里面return false就可以实现阻止upload自动上传
// 阻止upload的自己上传,进行再操作 beforeupload (file) { this.formData.append('file', file) return false }
关于图片和表单文件一起上传我们选择了formData格式存储数据用于上传
选择了图片并填写必填信息之后点击保存进行上传操作,在onSubmit方法里把表单信息都append到formData里that.$refs.uploadxls.submit() // 提交时触发了before-upload函数--》完成图片的上传即执行beforeupload方法
4、图片必填的验证问题:
a、如果没有选择图片点击保存则图片提示:请上传图片
b、此时选择了图片则“请上传图片”消失
验证规则里有一条file就是做图片必填验证的
file: [ { required: true, message: '请上传图片' } ]
c、在编辑重点人员信息时重点人员图片已存在没有进行图片上传操作此时点击保存应该不提示“请上传图片”,未解决这个问题我们在上传时添加判断:
如果是编辑信息且未进行过图片上传操作则去掉file验证
就是以下代码
that.rules.file = [{ required: true, message: '请上传图片' }] if (that.dialogType !== 'add' && !this.doUpload) { that.rules.file = [] that.$refs['uploadElement'].clearValidate() }
整个弹框组件的代码如下:
<template> <div> <el-form :inline="true" ref="addKeyPersonForm" :model="addKeyPersonForm" label-width="1.4rem" :rules="rules"> <el-form-item label="姓名:" prop="name"> <el-input v-model="addKeyPersonForm.name" placeholder="请输入姓名"></el-input> </el-form-item> <el-form-item label="性别:" label-width="0.64rem" prop="sex"> <el-select v-model="addKeyPersonForm.sex" placeholder="请选择"> <el-option label="男" value="1"></el-option> <el-option label="女" value="2"></el-option> </el-select> </el-form-item> <el-form-item label="年龄:" label-width="0.64rem" prop="age"> <el-input v-model="addKeyPersonForm.age" placeholder="请输入"></el-input> </el-form-item> <el-form-item prop="file" ref="uploadElement"> <el-upload :style="{backgroundImage:'url(' + dialogImageUrl + ')', backgroundRepeat:'no-repeat', backgroundPosition:'center center', backgroundSize: 'contain'}" ref="uploadxls" action="aaa" ::limit="1" :show-file-list="false" :on-change="handlePictureCardPreview" :before-upload="beforeupload" accept="image/png,image/gif,image/jpg,image/jpeg"> <i v-show="!dialogImageUrl"></i> <div v-show="!dialogImageUrl" slot="tip">上传照片</div> </el-upload> </el-form-item> <!--<img :src="dialogImageUrl"/>--> <el-form-item label="身份证号:" prop="idCard"> <el-input v-model="addKeyPersonForm.idCard" placeholder="请输入身份证号"></el-input> </el-form-item> <el-form-item label="国籍:" label-width="0.64rem" prop="nationlity"> <el-select v-model="addKeyPersonForm.nationlity" placeholder="请选择"> <el-option label="中国" value="中国"></el-option> </el-select> </el-form-item> <el-form-item label="车牌号:" prop="plateNumber"> <el-input v-model="addKeyPersonForm.plateNumber" placeholder="请输入车牌号"></el-input> </el-form-item> <el-form-item label="类别:" label-width="0.64rem" prop="userType"> <!--<el-select v-model="addKeyPersonForm.userType" placeholder="请选择"> <el-option label="精神病人" value="0"></el-option> <el-option label="涉毒" value="1"></el-option> </el-select>--> <el-select v-model="addKeyPersonForm.userType" placeholder="请选择"> <el-option v-for="item in keyPersonType" :key="item.id" :label="item.dataValue" :value="item.dataKey"> {{item.dataValue}} </el-option> </el-select> </el-form-item> <el-form-item label="户籍地:" prop="registered"> <!-- <el-select v-model="addKeyPersonForm.huji" placeholder="请选择"> <el-option label="青岛市" value="0"></el-option> <el-option label="北京市" value="1"></el-option> </el-select>--> <el-cascader :options="options" placeholder="请选择" v-model="addKeyPersonForm.registered" :rules="{type: 'array'}" @change="handleChange" :separator="' '"> </el-cascader> </el-form-item> <el-form-item prop="registeredDetails"> <el-input v-model="addKeyPersonForm.registeredDetails" placeholder="请输入详细地址"></el-input> </el-form-item> <el-form-item label="居住地:" prop="domicile"> <!--<el-select v-model="addKeyPersonForm.juzhu" placeholder="请选择"> <el-option label="青岛市" value="0"></el-option> <el-option label="北京市" value="1"></el-option> </el-select>--> <el-cascader :options="options" placeholder="请选择" :rules="{type: 'array'}" v-model="addKeyPersonForm.domicile" @change="handleChange" :separator="' '"> </el-cascader> </el-form-item> <el-form-item prop="domicileDetails"> <el-input v-model="addKeyPersonForm.domicileDetails" placeholder="请输入详细地址"></el-input> </el-form-item> <el-form-item label="经纬度:"> <el-input v-model="position" placeholder="请选择经纬度" @click.native="showPosition=true"></el-input> </el-form-item> <!--<el-form-item label="所属人员库:"> <el-select v-model="addKeyPersonForm.library" placeholder="请选择"> <el-option label="全国重点人员库1" value="0"></el-option> <el-option label="全国重点人员库2" value="1"></el-option> </el-select> </el-form-item>--> <el-form-item label="问题及现实表现:" prop="problem"> <el-input v-model="addKeyPersonForm.problem" placeholder="请输入问题及现实表现"></el-input> </el-form-item> <el-form-item label="采取措施:" prop="measure"> <el-input v-model="addKeyPersonForm.measure" placeholder="请输入措施"></el-input> </el-form-item> <el-form-item label="控制人员:" prop="controller"> <el-table :data="addKeyPersonForm.controller" stripe> <el-table-column prop="name" label="姓名" show-overflow-tooltip> </el-table-column> <el-table-column prop="sex" label="性别"> </el-table-column> <el-table-column prop="birth" show-overflow-tooltip label="出生日期"> </el-table-column> <el-table-column prop="post" show-overflow-tooltip label="职务"> </el-table-column> <el-table-column prop="phone" show-overflow-tooltip label="联系电话"> </el-table-column> <el-table-column label="操作"> <template slot-scope="scope"> <el-button @click.native.prevent="deleteRow(scope.$index)" type="text" size="small"> 移除 </el-button> </template> </el-table-column> </el-table> <el-button type="text" icon="el-icon-plus" @click="innerVisible = true">继续添加</el-button> </el-form-item> <el-form-item label="备注:" prop="remark"> <el-input type="textarea" rows="1" v-model="addKeyPersonForm.remark" placeholder="请输入备注"></el-input> </el-form-item> <el-form-item label="最后更新时间:" v-if="addKeyPersonForm.updateTime"> <p>{{addKeyPersonForm.updateTime}}</p> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit" :disabled="doSubmitFlag">保存</el-button> </el-form-item> </el-form> <!--添加控制人员弹框------------------开始--> <el-dialog title="添加控制人员" v-if="innerVisible" :visible.sync="innerVisible" append-to-body :before-close="closeFun"> <personnel-control-add @add-person="addPerson" ref="addForm"></personnel-control-add> </el-dialog> <!--添加控制人员弹框------------------结束--> <!--选择经纬度弹框------------------开始--> <el-dialog title="选择经纬度" v-if="showPosition" :visible.sync="showPosition" append-to-body :before-close="closePosition"> <personnel-add-position ref="addPosition" @add-position="addPosition" :position-form1="positionForm"></personnel-add-position> </el-dialog> <!--选择经纬度弹框------------------结束--> </div> </template>