[关闭]
@Bios 2020-02-11T13:39:04.000000Z 字数 7161 阅读 845

我在实际项目开发中遇到的关于ElementUI各种表单验证

ElementUi


博客原文地址https://finget.github.io/2020/02/11/element-form/

第一种 最简单的必填字段

  1. <el-form-item
  2. label="委托方"
  3. prop="real_operator_id"
  4. >
  5. <operators-select v-model="form.real_operator_id"></operators-select>
  6. </el-form-item>
  1. rules: {
  2. real_operator_id: {required: true, message: '请选择委托方', trigger: 'change'}
  3. }

第二种 正则验证字段

  1. <el-form-item
  2. label="容纳人数"
  3. prop="capacity"
  4. >
  5. <el-input
  6. v-model="form.capacity"
  7. placeholder="请输入容纳人数"
  8. ></el-input>
  9. </el-form-item>
  1. rules:{
  2. capacity: [
  3. {required: true, message: '请输入容纳人数', trigger: 'change'},
  4. {pattern: /^[1-9][0-9]{0,3}$/, message: '只能输入正整数,且不超过4位数', trigger: 'change'}],
  5. }

⚠️什么电话、邮箱、数字、英文、汉字...等能用正则验证都可以用这个方式。

第三种 富文本必填验证

  1. <el-form-item
  2. label="政策内容"
  3. prop="content"
  4. >
  5. <Tinymce
  6. ref="editor"
  7. v-model="form.content"
  8. :height="300"
  9. />
  10. <el-input
  11. v-model="form.content"
  12. style="display:none;"
  13. ></el-input>
  14. </el-form-item>
  1. rules: {
  2. content: [
  3. {required: true, message: '请填写政策内容', trigger: 'change'}
  4. ],
  5. }

这里采用一个骚操作,原本输入框的验证都是监听的输入框的各种事件(change,blur),然而富文本都是第三方插件,无法监听到,所以就利用了vue的双向绑定原理,写一个隐藏的输入框,搞定。

第四种 多个输入框

  1. <el-form-item
  2. label="关联写字楼"
  3. prop="building_id"
  4. >
  5. <div class="display-flex align-items-center">
  6. <el-select
  7. v-model="form.building_id"
  8. filterable
  9. remote
  10. placeholder="请输入写字楼名称"
  11. :remote-method="getProjectLists"
  12. :loading="loading"
  13. @change="getBuilding">
  14. <el-option
  15. v-for="item in projectOptions"
  16. :key="item.id"
  17. :label="item.project_name"
  18. :value="item.id">
  19. </el-option>
  20. </el-select>
  21. <el-select
  22. class="marginL10"
  23. v-if="form.building_id"
  24. v-model="form.building_detail.id"
  25. placeholder="请选择楼栋"
  26. @change="getUnit">
  27. <el-option
  28. v-for="item in buildingList"
  29. :key="item.id"
  30. :label="item.building_name"
  31. :value="item.id">
  32. </el-option>
  33. </el-select>
  34. <el-select
  35. class="marginL10"
  36. v-if="unitList.length && form.building_detail.id"
  37. v-model="form.building_detail.unit_id"
  38. placeholder="请选择单元"
  39. @change="changeUnit">
  40. <el-option
  41. v-for="item in unitList"
  42. :key="item.id"
  43. :label="item.unit"
  44. :value="item.id">
  45. </el-option>
  46. </el-select>
  47. <numberInput
  48. :append="'层'"
  49. :isDecimal="false"
  50. :intlength="4"
  51. :placeholder="'请输入楼层'"
  52. v-model="form.building_detail.floor"></numberInput>
  53. </div>
  54. </el-form-item>
  1. data() {
  2. let checkBuilding = (rule, value, callback) => {
  3. if (!this.form.building_id) {
  4. callback(new Error('请选择写字楼'));
  5. } else if (!this.form.building_detail.id) {
  6. callback(new Error('请选择楼栋'));
  7. } else if (this.unitList.length && !this.form.building_detail.unit_id) {
  8. callback(new Error('请选择单元'));
  9. } else if (!this.form.building_detail.floor) {
  10. callback(new Error('请填写楼层'));
  11. } else {
  12. callback();
  13. }
  14. };
  15. return {
  16. rules: {
  17. building_id: {required: true, validator: checkBuilding, trigger: 'change'},
  18. }
  19. }
  20. }

第五种 动态验证-普通的动态验证

官网拷贝的代码,占个位置。

  1. <el-form-item
  2. v-for="(domain, index) in dynamicValidateForm.domains"
  3. :label="'域名' + index"
  4. :key="domain.key"
  5. :prop="'domains.' + index + '.value'"
  6. :rules="{
  7. required: true, message: '域名不能为空', trigger: 'blur'
  8. }"
  9. >
  10. <el-input v-model="domain.value"></el-input>
  11. <el-button @click.prevent="removeDomain(domain)">删除</el-button>
  12. </el-form-item>

第六种 动态验证-多个输入框验证

第一种情况 每个输入框单独验证

在样式很好控制的情况下,循环生成多个<el-form-item>,单独验证

  1. <div
  2. v-for="(item,index) in form.project"
  3. :key="index"
  4. >
  5. <div class="display-flex">
  6. <el-form-item
  7. :label="index==0?'关联写字楼':''"
  8. :prop="'project.' + index + '.project_id'"
  9. :rules="{required: true, message: '请选择关联写字楼', trigger: 'blur'}">
  10. <el-select
  11. v-model="item.project_id"
  12. filterable
  13. clearable
  14. remote
  15. reserve-keyword
  16. placeholder="请输入关键词"
  17. :remote-method="getProjectLists"
  18. :loading="loading"
  19. @change="projectChange($event,index)">
  20. <el-option
  21. v-for="item in projectOptions"
  22. :key="item.id"
  23. :label="item.project_name"
  24. :value="item.id">
  25. </el-option>
  26. </el-select>
  27. </el-form-item>
  28. <el-form-item
  29. label-width="20px"
  30. :prop="'project.' + index + '.building_id'"
  31. :rules="{required: true, message: '请选择关联写字楼楼栋', trigger: 'blur'}">
  32. <el-select
  33. v-model="item.building_id"
  34. placeholder="请选择楼栋"
  35. @change="buildChange($event,index)">
  36. <el-option
  37. v-for="item in item.buildOptions"
  38. :key="item.id"
  39. :label="item.building_name"
  40. :value="item.id">
  41. </el-option>
  42. </el-select>
  43. </el-form-item>
  44. <el-form-item
  45. v-if="item.unitOptions && item.unitOptions.length"
  46. label-width="20px"
  47. :prop="'project.' + index + '.unit_id'"
  48. :rules="{required: true, message: '请选择关联写字楼单元', trigger: 'blur'}">
  49. <el-select
  50. v-model="item.unit_id"
  51. placeholder="请选择单元">
  52. <el-option
  53. v-for="item1 in item.unitOptions"
  54. :key="item1.id"
  55. :label="item1.unit"
  56. :value="item1.id">
  57. </el-option>
  58. </el-select>
  59. </el-form-item>
  60. <el-form-item
  61. label="所在楼层"
  62. :prop="'project.' + index + '.floor'"
  63. :rules="[{required: true, message: '请填写所在楼层', trigger: 'blur'},
  64. {pattern: /^([1-9][0-9]{0,2})$/,message:'只能输入正整数,且不超过三位数',trigger:'change'}]">
  65. <div class="display-flex">
  66. <el-input
  67. v-model.number="item.floor"
  68. placeholder="请填写楼层,3位数以内"
  69. autocomplete="off">
  70. <el-button slot="append"></el-button>
  71. </el-input>
  72. </div>
  73. </el-form-item>
  74. </div>
  75. </div>

第二种情况 统一验证

有的时候,迫于样式的困扰,我们只能写多个输入框,而不能生成多个<el-form-item>,在同一个<el-form-item>下统一验证

  1. <div style="list-style:none;"
  2. v-for="(item, index) in form.rules"
  3. :key="index">
  4. <el-form-item
  5. :label="index == 0?'添加规则(未到使用时间)':''"
  6. :prop="'rules.'+index+'.hours'"
  7. :rules ="{required:true, validator:checkRules , trigger: 'change'}">
  8. <div class="display-flex li-box">
  9. <div>
  10. <span>使用前 </span>
  11. <numberInput
  12. class="small-input"
  13. size="small"
  14. v-model="item.hours"
  15. :isDecimal="false"
  16. :intlength="4"
  17. :clearable="false"
  18. placeholder=""/>
  19. <span> 小时取消,扣除订单总额 </span>
  20. <numberInput
  21. class="small-input"
  22. size="small"
  23. v-model="item.percent"
  24. :isDecimal="false"
  25. :clearable="false"
  26. :intlength="3"
  27. placeholder=""/>
  28. <span> %费用(不含保证金)</span>
  29. </div>
  30. </div>
  31. </el-form-item>
  32. </div>

rule长这样:

  1. methods: {
  2. // 验证rule
  3. checkRules(rule, value, callback) {
  4. // 通过rule.field 拿到index ,剩下的都常规操作了
  5. let index = rule.field.split('.')[1] - 0;
  6. if (!this.form.rules[index].hours || !this.form.rules[index].percent) {
  7. callback(new Error('请填写规则'));
  8. } else if (Number(this.form.rules[index].percent) > 100) {
  9. callback(new Error('百分比不能超过100%'));
  10. } else {
  11. callback();
  12. }
  13. },
  14. }

第七种 动态验证-关联验证

填了租金才会触发对应的租金时间段验证

  1. <div
  2. v-for="(item, index) in form.payment.rent_period"
  3. :key="'rent' + index"
  4. >
  5. <el-form-item
  6. :label="'租金'+(index+1)"
  7. class="flex-1"
  8. :prop="'payment.rent_period.'+index+'.rent_fee'"
  9. :rules ="{validator:moneyValidator, trigger:'change'}"
  10. >
  11. </el-form-item>
  12. <el-form-item
  13. class="flex-1"
  14. label="租金时间段"
  15. :prop="'payment.rent_period.'+index+'.start_time'"
  16. // 就是这里判断一下item.rent_fee是否存在
  17. :rules="item.rent_fee?{required: true, message:'请填写租金时间段', trigger: 'change'}:{}">
  18. </el-form-item>
  19. </div>

第八种 动态验证-判重

  1. <el-form-item
  2. v-for="(item,index) in industryForm.follow"
  3. :key="item.id"
  4. :label="'关注行业'+(index+1)"
  5. :prop="'follow.'+index+'.industry'"
  6. :rules="{validator: attentionIndustryValidator, trigger:'change'}"
  7. >
  8. ....
  9. </el-form-item>
  1. attentionIndustryValidator(rule, val, callback) {
  2. let num = 0;
  3. this.industryForm.follow.forEach(item => {
  4. // 这里做一次数组判重
  5. if (this.equals(val, item.industry)) {
  6. num++;
  7. }
  8. });
  9. if (num >= 2) {
  10. callback(new Error('请勿重复选择相同的行业!'));
  11. } else {
  12. callback();
  13. }
  14. },

第九种 清除某一个输入项验证

如图开始选择了意向类型为按面积,此时已经验证了意向面积的值,并提示错误信息,然后切换为按工位,如果不清除意向面积的验证,则错误信息会一直存在

  1. <el-form-item
  2. ref="areaForm"
  3. prop="intention_area"
  4. :label="form.intention_type==1?'意向面积':'意向工位'"
  5. :label-width="formLabelWidth"
  6. :rules="[{required:true, validator: areaValidator, trigger:'blur'}]">
  7. ...
  8. </el-form-item>
  1. watch: {
  2. 'form.intention_type': {
  3. handler() {
  4. this.$refs['areaForm'].clearValidate();
  5. }
  6. }
  7. },

最后

我们自定义验证(validator),有两种方式。

  1. data() {
  2. let testrule1 = (rule,val,callback) => {};
  3. return {}
  4. }

使用方式是在data中的rule里引入:

  1. data(){
  2. let testRule1 = (rule,val,callback) => {};
  3. return {
  4. rules: {
  5. name:{required: true, validator:testRule1, trigger:'blur'}
  6. }
  7. }
  8. }
  1. methods: {
  2. testRule2(rule, val, callback) {}
  3. }

使用方式是在<el-form-item>中引入:

  1. <el-form-item
  2. prop="name"
  3. :rules="{required:true, validator: testRule2, trigger:'blur'}">
  4. ...
  5. </el-form-item>
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注