扩展element-ui校验规则

扩展element-ui校验规则

1.现状分析

我们使用的前端框架目前主要是element-ui和vant,老版本的甚至还有使用vux.不管那个框架在使用时都涉及到对输入表单的校验.
翻看官方的文档发现底层实现大多都是利用相应的验证框架, 对应版本如下:
element-ui 2.15.1 ====> async-validator 1.8.5, 最新版本是3.5.1
vux 2.9.4		  ====> "validator": "^9.3.0",	
vant 2.12.14      ====> 没有内置验证框架,不过可以自定义
常用的验证框架也不少,vuelidate, vee-validate, validator, async-validator

其中pc端主要是用element-ui组件库,对表单的验证规则限制比较多,比如像身份证验证,手机号码验证,虽然可以通过正则表达式来自己定义.
总感觉还是比较麻烦,如果能够扩展,自己定义一些规则, 把常用的验证抽取出来统一放到一个文件,统一设置,然后统一使用,
然后在程序的任何地方都能够应用就比较完美了.

比如要验证身份证号码:	只需要指定以下规则
	{ type: 'id', message: '身份证号码格式错误', trigger:['blur','change']},
比如要验证手机号码: 只需要指定以下规则
	{ type: 'mobile', message: '手机号码格式错误', trigger:['blur','change']},
这样岂不是很爽啊.

2.分析问题

我翻遍官网的文档(element-ui,async-validator),都没有找到如何扩展form已有的校验规则.
不得已只好找出async-validator源代码来分析, 大概浏览了一下,发现有以下的代码片段

在async-validator源码的src/index.js中发现了这样一个静态函数,似乎是注册某种类型的校验器的.

Schema.register = function register(type, validator) {
  if (typeof validator !== 'function') {
	throw new Error('Cannot register a validator by type, validator is not a function');
  }
  validators[type] = validator;
};

发现validators对象是系统定义的validator的容器,框架自带的类型校验器都在该对象中.
而我们看到Schema.register函数也是把传入的校验器保存到这个对象容器中.
这个函数在框架中都没找到地方调用,会不会就是提供给我们扩展的呢.

可不可以我们自定义一些validator通过调用该方法放到容器中就生效了呢.

假设如果成立,那就要解决以下两个问题:

1.validator怎么编写
2.validator怎么注册

validator编写

通过观察系统自带的validator发现:

这个跟我们平时在使用校验规则的时候,自己定义的写法完全相同.
validator 本质上就是个函数,接受和待验证的输入框相关的参数.

找一个比较简单的系统默认的校验器来研究研究,比如number校验器,在源码src/validator/number.js中
内容如下:

/**
 *  校验一个数字
 *  @param rule  	单条的校验规则.其实就是使用是自己设置的规则对象
 *  @param value 	就是你在输入框中输入的值
 *  @param callback 回调函数.有参数表示校验失败,没参数表示成功.
 *  @param source   就是检查的哪个属性的那个取值,是一个对象.
 *  @param options  校验时的选项参数.包含
 *  {
 *		messages: '', //默认错误消息提示,这是个对象,包含默认情况下其他的type的校验器的提示信息
 *		firstFields: true // 第一个字段检查之如果错误,就不检查后面的字段
 *	}
 */
function number(rule, value, callback, source, options) {
  const errors = [];
  const validate = rule.required || (!rule.required && source.hasOwnProperty(rule.field));
  if (validate) {
    if (isEmptyValue(value) && !rule.required) {
      return callback();
    }
    rules.required(rule, value, source, errors, options);
    if (value !== undefined) {
      rules.type(rule, value, source, errors, options);
      rules.range(rule, value, source, errors, options);
    }
  }
  callback(errors);
}

就是在这个函数中做逻辑校验的,经验证对于以下规则是有效的.

{ type: 'number', message: '必须是数字格式', trigger:['blur','change']},

validator注册

发现系统自带的validator都导入到validators对象中了,并没有调用注册函数.
估计是我们外部扩展的才需要定义调用注册函数来注册.
	Schema.register('id',validId);  
这里的第一个参数就是type,第二个参数就是validator函数名了.

3.最佳实践

虽然理论上没问题,总得实践下

1.编写扩展校验器并注册

在项目的/src/plugins/validate.js文件中增加以下内容:
// 导入框架
import Schema from 'async-validator';

// 身份证号码校验器
function validId(rule, value, callback){
  if(value){ // '', undefined
	let reg=/^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
    if(!reg.test(value)){callback(new Error('身份证号码不正确'));}	  
  }else{
      callback();
  }
}

// 注册身份证号码校验器
Schema.register('id',validId);         

2.导入扩展校验器

在项目的src/main.js文件中增加一行内容

import '@/plugins/validate'; //自定义校验

3.在组件中使用

<el-form :rules="rules" ref="ruleForm" :model="form" label-width="120px" size="small">
	<el-form-item label="名称" prop="ident">
	  <el-input placeholder="英文名称" v-model="form.ident" style="width:48%" required/>
	</el-form-item>
</el-form>

<script>
export default {
	data() {
		form: { ident: ''},
		rules: {
			ident: [
			  { type: 'id', message: '身份证号码格式错误', trigger:['blur','change']},
			  { required: true, message: '必须输入身份证号码', trigger:['blur','change']},
			]
		}
	}
}	
</script>

{ type: ‘id’, message: ‘身份证号码格式错误’, trigger:[‘blur’,‘change’]},

只需要定义校验规则{type: ‘id’}, 就能使用到我们在全局扩展的校验器.
这种方式确实比在每个表单都去定义要方便多了.

经过验证确实证明我们的猜想是正确的.

4.总结

只需要写好自己的validator并调用框架提供的注册函数注册的校验器,即可在全局使用.
把我们项目中用到的校验规则统一写成校验器.应该能省不少事情.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值