Open tiodot opened 7 years ago
在使用antd的form表单组件时,可以发现其已经实现这样的一个校验器了——async-validator,其基本用法可以参考async-validator使用,然后之前也分析过其源码,觉得其代码组织很好,将不同的基本校验规则拆分成不同的模块,然后以组合方式使用,支持的校验规则也很全面。但有一点,校验逻辑那块代码甚是复杂。于是基于async-validator,改造了一下其源码。
async-validator没有提供动态添加校验规则的api,虽然可以实现,却也有点繁琐,故新增一个extendapi用于动态添加校验规则。
extend
validate
移除一些无关紧要,或者说使用频率较低的功能点:
整体概述: 原理很简单,实现当然也不会很复杂:
Schema
代码结构为:
class Schema { constructor(descriptor) { this.rules = null; this.define(descriptor); } define(rules) {} extend(rules) {} validate(source, options = {}, callback) {} static register(type, validator) {} }
rules的格式为:
{ name: {type: "string", required: true} // name 为字段名称,其值为改字段的验证规则 }
define和extend都是接受校验规则,其唯一区别就是define会清空this.rules。 至于validate则是根据给的值,然后匹配对应的校验规则进行验证,核心代码为:
this.rules
validate(source, options = {}, callback) { const keys = options.keys || Object.keys(this.rules); const errors = []; for (let key of keys) { const rules = this.rules[key]; let value = source[key]; for (let rule of rules) { let tempError = rule.validator(rule, value, source, options); // 直接返回string或者new Error('xxx')形式 if (typeof tempError === 'string' || tempError.message) { tempError = [tempError]; } if (Array.isArray(tempError) && tempError.length) { if (rule.message) { tempError = [].concat(rule.message); } errors.push(...tempError); break; } } } callback(errors.length ? errors : null); }
最后是提供一个校验规则函数的register接口,所有的校验规则函数都存储在validators,简单的说这个就是一个Object,其形式为:
validators
validators = { required: function(rule, value, source, options){/*对value进行空值判断*/}, number: function(rule, value, source, options){...} .... }
所以扩展也极其简单:
static register(type, validator) { if (typeof validator !== 'function') { throw new Error('Cannot register a validator by type, validator is not a function'); } validators[type] = validator; }
前言
16 中提到要实现一个能直接使用jsx语法表示的React表单验证器。因而至少需要达到以下两个要求:
在使用antd的form表单组件时,可以发现其已经实现这样的一个校验器了——async-validator,其基本用法可以参考async-validator使用,然后之前也分析过其源码,觉得其代码组织很好,将不同的基本校验规则拆分成不同的模块,然后以组合方式使用,支持的校验规则也很全面。但有一点,校验逻辑那块代码甚是复杂。于是基于async-validator,改造了一下其源码。
改造点
新增
async-validator没有提供动态添加校验规则的api,虽然可以实现,却也有点繁琐,故新增一个
extend
api用于动态添加校验规则。优化
validate
api里面的代码逻辑移除
移除一些无关紧要,或者说使用频率较低的功能点:
实现
整体概述: 原理很简单,实现当然也不会很复杂:
Schema
来保存校验规则代码结构为:
rules的格式为:
define和extend都是接受校验规则,其唯一区别就是define会清空
this.rules
。 至于validate则是根据给的值,然后匹配对应的校验规则进行验证,核心代码为:最后是提供一个校验规则函数的register接口,所有的校验规则函数都存储在
validators
,简单的说这个就是一个Object,其形式为:所以扩展也极其简单:
参考