gpt4 book ai didi

async-validator 源码学习笔记(五):Schema

转载 作者:知者 更新时间:2024-03-13 03:22:51 30 4
gpt4 key购买 nike

系列文章:

1、async-validator 源码学习(一):文档翻译

2、async-validator 源码学习笔记(二):目录结构

3、async-validator 源码学习笔记(三):rule

4、async-validator 源码学习笔记(四):validator

Schema 是 async-validator 库的标准使用方式,使用 class 类的形式和构造函数方式进行定义的。

一、Schema 类使用方式

在官方文档中 Schema 的使用方式有如下几步:

  1. 从 async-validator 中引入 Schema 类。
  2. 定义校验规则 descriptor 。
  3. 使用 new 创建一个 Schema 的实例。
  4. 调用实例的 validate 方法。

使用 demo:

//引入
import Schema from 'async-validator'
//定义校验规则
const descriptor  ={
 username: {
  type: 'string',
  required: true,
  validator(rule, value) {
   return value != ''},
  message: '用户名不能为空',
 }
}
//实例化
const validator = newSchema(descriptor )
//开始校验
validator.validate({ username:'需要验证的值' },(error, fields) =>{
 if(errors){
  //校验失败
   returnhandleError( errors, fields )
 }
 //校验成功 
})
//或者 promise 用法
validator.validate({ username:'需要验证的值'})
.then(res =>{
 //校验成功
})
.catch(({errors,fields}) =>{
//校验失败
})

new Schema(descriptor ) 直接开始实例化了,我们看看 Schema 是如何定义的?

二、Schema 源码分析

Schema 的构造函数:主要分为三步:

1、this 上定义实例属性 rules 为 null。

//构造函数
var Schema = function() {
  functionSchema(descriptor) {
    //1、实例属性 rules 默认值为空 
    this.rules = null;
    //2、私有属性 _messages 设置初始化值
    this._messages =messages;
    //3、正式开始构建实例
    this.define(descriptor);
  }
  returnSchema;
}();
Schema.warning =warning;
Schema.messages =messages;
Schema.validators =validators;

exports['default'] = Schema;

2、this 上定义一个实例私有属性 _message ,初始化值为:

functionnewMessages() {
  ...
}
var messages = newMessages();

3、调用原型链 define 方法,传参 descriptor 。

descriptor 是实例化时传入的校验规则。

由上可以看到,Schema 原型链上 添加了 register、warning、messages、validators 四个方法。

2.1、warning

在实例化 Schema 之前设置 warning 方法,只要 warning 方法设置为一个空函数就能够屏蔽控制台警告。

Schema.warning = () =>{}
//don't print warning message when in production env or node runtime

可以发现 warning 本身就被设为了一个空函数,只有在开发环境或非 node运行时,才会用 console.warn 打印出 errors 数组中的每一个 error。

var warning = functionwarning() {}; 
//don't print warning message when in production env or node runtime

if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV !== 'production' && typeof window !== 'undefined' && typeof document !== 'undefined') {
  warning = functionwarning(type, errors) {
    if (typeof console !== 'undefined' && console.warn && typeof ASYNC_VALIDATOR_NO_WARNING === 'undefined') {
      if (errors.every(function(e) {
        return typeof e === 'string';
      })) {
        console.warn(type, errors);
      }
    }
  };
}

2.2、message

Schema 中的 message 方法实质是根据不同类型校验失败后错误提示使用的提示信息模板。官方提供了一个默认的模板:

functionnewMessages() {
  return{
    "default": 'Validation error on field %s',
    required: '%s is required',
    "enum": '%s must be one of %s',
    whitespace: '%s cannot be empty',
    date: {
      format: '%s date %s is invalid for format %s',
      parse: '%s date could not be parsed, %s is invalid ',
      invalid: '%s date %s is invalid'},
    types: {
      string: '%s is not a %s',
      method: '%s is not a %s (function)',
      array: '%s is not an %s',
      object: '%s is not an %s',
      number: '%s is not a %s',
      date: '%s is not a %s',
      "boolean": '%s is not a %s',
      integer: '%s is not an %s',
      "float": '%s is not a %s',
      regexp: '%s is not a valid %s',
      email: '%s is not a valid %s',
      url: '%s is not a valid %s',
      hex: '%s is not a valid %s'},
    string: {
      len: '%s must be exactly %s characters',
      min: '%s must be at least %s characters',
      max: '%s cannot be longer than %s characters',
      range: '%s must be between %s and %s characters'},
    number: {
      len: '%s must equal %s',
      min: '%s cannot be less than %s',
      max: '%s cannot be greater than %s',
      range: '%s must be between %s and %s'},
    array: {
      len: '%s must be exactly %s in length',
      min: '%s cannot be less than %s in length',
      max: '%s cannot be greater than %s in length',
      range: '%s must be between %s and %s in length'},
    pattern: {
      mismatch: '%s value %s does not match pattern %s'},
    clone: functionclone() {
      var cloned = JSON.parse(JSON.stringify(this));
      cloned.clone = this.clone;
      returncloned;
    }
  };
}
var messages = newMessages();

上述是官方提供的默认模板提示信息,还可以根据自己的项目进行定制化,因为官方也提供了 deepMerge 方法:

_proto.messages = functionmessages(_messages) {
    if(_messages) {
      this._messages =deepMerge(newMessages(), _messages);
    }
    return this._messages;
  };
/*深度合并 */
functiondeepMerge(target, source) {
  if(source) {
    //更新 message
    for (var s insource) {
      if(source.hasOwnProperty(s)) {
        var value =source[s];

        if (typeof value === 'object' && typeof target[s] === 'object') {
          target[s] =_extends({}, target[s], value);
        } else{
          target[s] =value;
        }
      }
    }
  }
  returntarget;
}

所以可以根据自己项目需求,可以自己定制化一个 message 校验提示。

2.3、validators

validator 主要作用是为用户提供各种数据类型的验证方法。

var validators ={
  string: string,
  method: method,
  number: number,
  "boolean": _boolean,
  regexp: regexp,
  integer: integer,
  "float": floatFn,
  array: array,
  object: object,
  "enum": enumerable,
  pattern: pattern,
  date: date,
  url: type,
  hex: type,
  email: type,
  required: required,
  any: any
};

以对string类型的判断为例

rule: 在源descriptor中,与要校验的字段名称相对应的校验规则。始终为它分配一个field属性,其中包含要验证的字段的名称。

//这个样子
{
    [field: string]: RuleItem |RuleItem[]
}
//例子
{name:{type: "string", required: true, message: "Name is required"}}

2.4、register

除了 validators 方法,还提供了 register 方法,用于新增类型校验器:

Schema.register = functionregister(type, validator) {
  //validator 必须是函数
  if (typeof validator !== 'function') {
    //无法按类型注册验证程序,验证程序不是函数
    throw new Error('Cannot register a validator by type, validator is not a function');
  }
  
  validators[type] =validator;
};

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com