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

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

第一种 最简单的必填字段

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

第二种 正则验证字段

<el-form-item label="容纳人数" prop="capacity">
  <el-input v-model="form.capacity" placeholder="请输入容纳人数"/>
</el-form-item>
rules:{
  capacity: [
    {required: true, message: '请输入容纳人数', trigger: 'change'},
    {pattern: /^[1-9][0-9]{0,3}$/, message: '只能输入正整数,且不超过4位数', trigger: 'change'}],
}
⚠️什么电话、邮箱、数字、英文、汉字...等能用正则验证都可以用这个方式。

第三种 富文本必填验证

<el-form-item label="政策内容" prop="content">
  <Tinymce ref="editor" v-model="form.content" :height="300"/>
  <el-input v-model="form.content" style="display:none;"/>
</el-form-item>
rules: {
  content: [
    {required: true, message: '请填写政策内容', trigger: 'change'}
  ],
}
这里采用一个骚操作,原本输入框的验证都是监听的输入框的各种事件(change,blur),然而富文本都是第三方插件,无法监听到,所以就利用了vue的双向绑定原理,写一个隐藏的输入框,搞定。

第四种 多个输入框

<el-form-item label="关联写字楼" prop="building_id">
  <div class="display-flex align-items-center">
    <el-select v-model="form.building_id" filterable="" remote="" placeholder="请输入写字楼名称" :remote-method="getProjectLists" :loading="loading" @change="getBuilding">
        <el-option v-for="item in projectOptions" :key="item.id" :label="item.project_name" :value="item.id">
        </el-option>
    </el-select>
    <el-select class="marginL10" v-if="form.building_id" v-model="form.building_detail.id" placeholder="请选择楼栋" @change="getUnit">
        <el-option v-for="item in buildingList" :key="item.id" :label="item.building_name" :value="item.id">
        </el-option>
    </el-select>
    <el-select class="marginL10" v-if="unitList.length && form.building_detail.id" v-model="form.building_detail.unit_id" placeholder="请选择单元" @change="changeUnit">
        <el-option v-for="item in unitList" :key="item.id" :label="item.unit" :value="item.id">
        </el-option>
    </el-select>
    <numberInput :append="'层'" :isDecimal="false" :intlength="4" :placeholder="'请输入楼层'" v-model="form.building_detail.floor"/>
  </div>
</el-form-item>
data() {
  let checkBuilding = (rule, value, callback) => {
    if (!this.form.building_id) {
        callback(new Error('请选择写字楼'));
    } else if (!this.form.building_detail.id) {
        callback(new Error('请选择楼栋'));
    } else if (this.unitList.length && !this.form.building_detail.unit_id) {
        callback(new Error('请选择单元'));
    } else if (!this.form.building_detail.floor) {
        callback(new Error('请填写楼层'));
    } else {
        callback();
    }
  };
  return {
    rules: {
      building_id: {required: true, validator: checkBuilding, trigger: 'change'},
    }
  }
}

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

官网拷贝的代码,占个位置。
<el-form-item v-for="(domain, index) in dynamicValidateForm.domains" :label="'域名' + index" :key="domain.key" :prop="'domains.' + index + '.value'" :rules="{
      required: true, message: '域名不能为空', trigger: 'blur'
    }">
    <el-input v-model="domain.value"/>
    <el-button @click.prevent="removeDomain(domain)">删除</el-button>
</el-form-item>

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

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

在样式很好控制的情况下,循环生成多个<el-form-item>,单独验证
<div v-for="(item,index) in form.project" :key="index">
<div class="display-flex">
  <el-form-item :label="index==0?'关联写字楼':''" :prop="'project.' + index + '.project_id'" :rules="{required: true, message: '请选择关联写字楼', trigger: 'blur'}">
      <el-select v-model="item.project_id" filterable="" clearable="" remote="" reserve-keyword="" placeholder="请输入关键词" :remote-method="getProjectLists" :loading="loading" @change="projectChange($event,index)">
          <el-option v-for="item in projectOptions" :key="item.id" :label="item.project_name" :value="item.id">
          </el-option>
      </el-select>
  </el-form-item>
  <el-form-item label-width="20px" :prop="'project.' + index + '.building_id'" :rules="{required: true, message: '请选择关联写字楼楼栋', trigger: 'blur'}">
      <el-select v-model="item.building_id" placeholder="请选择楼栋" @change="buildChange($event,index)">
          <el-option v-for="item in item.buildOptions" :key="item.id" :label="item.building_name" :value="item.id">
          </el-option>
      </el-select>
  </el-form-item>
  <el-form-item v-if="item.unitOptions && item.unitOptions.length" label-width="20px" :prop="'project.' + index + '.unit_id'" :rules="{required: true, message: '请选择关联写字楼单元', trigger: 'blur'}">
      <el-select v-model="item.unit_id" placeholder="请选择单元">
        <el-option v-for="item1 in item.unitOptions" :key="item1.id" :label="item1.unit" :value="item1.id">
        </el-option>
      </el-select>
  </el-form-item>
  <el-form-item label="所在楼层" :prop="'project.' + index + '.floor'" :rules="[{required: true, message: '请填写所在楼层', trigger: 'blur'},
      {pattern: /^([1-9][0-9]{0,2})$/,message:'只能输入正整数,且不超过三位数',trigger:'change'}]">
      <div class="display-flex">
        <el-input v-model.number="item.floor" placeholder="请填写楼层,3位数以内" autocomplete="off">
            <el-button slot="append">层</el-button>
        </el-input>
      </div>
  </el-form-item>
</div>
</div>

第二种情况 统一验证

有的时候,迫于样式的困扰,我们只能写多个输入框,而不能生成多个<el-form-item>,在同一个<el-form-item>下统一验证
<div style="list-style:none;" v-for="(item, index) in form.rules" :key="index">
  <el-form-item :label="index == 0?'添加规则(未到使用时间)':''" :prop="'rules.'+index+'.hours'" :rules="{required:true, validator:checkRules , trigger: 'change'}">
    <div class="display-flex li-box">
      <div> 
          <span>使用前 </span>
          <numberInput class="small-input" size="small" v-model="item.hours" :isDecimal="false" :intlength="4" :clearable="false" placeholder=""/>
          <span> 小时取消,扣除订单总额 </span>
          <numberInput class="small-input" size="small" v-model="item.percent" :isDecimal="false" :clearable="false" :intlength="3" placeholder=""/>
          <span> %费用(不含保证金)</span>
        </div>
    </div>
  </el-form-item>
</div>

rule长这样:


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

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

填了租金才会触发对应的租金时间段验证
<div v-for="(item, index) in form.payment.rent_period" :key="'rent' + index">
  <el-form-item :label="'租金'+(index+1)" class="flex-1" :prop="'payment.rent_period.'+index+'.rent_fee'" :rules="{validator:moneyValidator, trigger:'change'}">
  </el-form-item>
  <el-form-item class="flex-1" label="租金时间段" :prop="'payment.rent_period.'+index+'.start_time'" 就是这里判断一下item.rent_fee是否存在="" :rules="item.rent_fee?{required: true, message:'请填写租金时间段', trigger: 'change'}:{}">
  </el-form-item>
</div>

第八种 动态验证-判重

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

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

如图开始选择了意向类型为按面积,此时已经验证了意向面积的值,并提示错误信息,然后切换为按工位,如果不清除意向面积的验证,则错误信息会一直存在
<el-form-item ref="areaForm" prop="intention_area" :label="form.intention_type==1?'意向面积':'意向工位'" :label-width="formLabelWidth" :rules="[{required:true, validator: areaValidator, trigger:'blur'}]">
...
</el-form-item>
watch: {
  'form.intention_type': {
    handler() {
      this.$refs['areaForm'].clearValidate();
    }
  }
},

最后

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

  • 第一种 定义在data中
data() {
  let testrule1 = (rule,val,callback) => {};
  return {}
}

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

data(){
  let testRule1 = (rule,val,callback) => {};
  return {
    rules: {
      name:{required: true, validator:testRule1, trigger:'blur'}
    }
  }
}
  • 第二种 定义在methods中
methods: {
  testRule2(rule, val, callback) {}
}

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

<el-form-item prop="name" :rules="{required:true, validator: testRule2, trigger:'blur'}">
    ...
</el-form-item>
原文链接:segmentfault.com

上一篇:sqlite3-transactions
下一篇:vue:3年挖坑血与汗的教训

相关推荐

  • (vuejs学习)2、使用ElementUI(*)

    1.element安装 开发环境是win10,一到node官网下载node的.msi包安装,二到淘宝cpm镜像查看cpm镜像命令:npm install -g cnpm --registry=http...

    1 年前
  • 防止在jQuery中双重提交表单

    smhollowayAdam提出了一个问题:Prevent double submission of forms in jQuery,或许与您遇到的问题类似。 回答者Ramon BakkerNatha...

    3 年前
  • 通过SortableJS实现elementUItable拖动效果

    背景 目前elmenetUI的表格是不支持拖动的,但表格行拖动要求往往比较常见。通过引入sortableJS可以方便的让elementUI组件中的table支持拖动效果。

    5 个月前
  • 通过JavaScript跟踪表单更改的最佳方式是什么?

    Ricardo Acras提出了一个问题:What is the best way to track changes in a form via javascript?,或许与您遇到的问题类似。

    2 年前
  • 超详细 ElementUI 源码分析 —— Input

    最近在学习 Vue 框架,想深入了解一下组件化开发以及封装组件库的思想,而 ElementUI 作为这方面做的最好的也是最常用的组件库,它的源码一定有很多值得我们去学习的地方,所以去 ElementU...

    6 个月前
  • 谷歌浏览器禁止表单自动填充

    在项目开发期间发现谷歌浏览器有记住密码的功能,该功能有个问题就是一遇到input type=password就开始自动填充,同一个账户还好,就是bug了。找了一堆解决方案终于找到了办法,下面分享一下解...

    1 年前
  • 详细解读AngularJS中的表单验证编程

    需求 Name 必填 Username 非必填,最小长度3,最大长度8 Email 非必填,但必须是合法的email 验证未通过的表单不能提交 显示一个必填或者非法email格式的错误信息 如果正确...

    4 年前
  • 详细分析使用AngularJS编程中提交表单的方式

    在AngularJS出现之前,很多开发者就面对了表单提交这一问题。由于提交表单的方式繁杂而不同,很容易令人疯掉……然而现在看来,依然会让人疯掉。 今天,我们会看一下过去使用PHP方式提交的表单,现在如...

    4 年前
  • 记录Vue+elementUi的开发过程,小白一枚

    最近公司在用Vue+elementUi开发后台管理系统,因为新手,所以好多东西理解的不够透彻,上手野也慢,现在自己给自己做下开发的小记录,方便日后查看和纠错,欢迎大家指正。

    3 年前
  • 记一次 bug : 表单提交时携带不上文件数据

    前言 这段时间我负责的基于 coreui/vue 的后台管理项目遇到难题了。在开发商品上架功能时,表单提交时,上传的图片数据始终为空,参数携带不了。但在发送请求之前是可以正常打印文件数据的。

    5 个月前

官方社区

扫码加入 JavaScript 社区