async-validator 原始碼學習筆記(三):rule

前端人發表於2022-03-22

系列文章:

1、async-validator 原始碼學習(一):文件翻譯

2、async-validator 原始碼學習筆記(二):目錄結構

rule 主要實現的是校驗規則,檔案結構為下圖:

async-validator 原始碼學習筆記(三):rule

 

一、rule 目錄檔案介紹

其中 index.d.ts 檔案:

declare const _default: {
 required: import("..").ExecuteRule;
 whitespace: import("..").ExecuteRule;
 type: import("..").ExecuteRule;
 range: import("..").ExecuteRule;
 enum: import("..").ExecuteRule;
 pattern: import("..").ExecuteRule;
};
export default _default;

 

是 rule 目錄的統一出口管理,主要是給 errors 陣列新增對應的 error 。

required.d.ts 檔案:

import { ExecuteRule } from '../interface';
declare const required: ExecuteRule;
export default required;

 

主要作用是校驗必填欄位的規則。

其中 ExecuteRule 是來自於 interface.d.ts 檔案中的

// 摘自其中的一部分
export declare type ExecuteRule = (
 rule: InternalRuleItem, 
 value: Value, 
 source: Values, 
 errors: string[], 
 options: ValidateOption, 
 type?: string
) => void;
/**
 *  Performs validation for any type.
 *
 *  @param rule The validation rule.
 *  @param value The value of the field on the source object.
 *  @param callback The callback function.
 *  @param source The source object being validated.
 *  @param options The validation options.
 *  @param options.messages The validation messages.
 */

 

ExecuteRule 是統一定義的函式型別別名,統一了函式傳遞引數和返回值的型別。等價於:

declare const required(rule, value, source, errors, options, type) 

 

方法內的引數及其意義如下:

  • @param rule 校驗的規則
  • @param value 需要校驗欄位的當前值
  • @param source 需要校驗的欄位
  • @param errors 本次校驗將要去新增的 errors 陣列
  • @param options 校驗選項
  • @param options.message 校驗的 messages

type.d.ts

import { ExecuteRule } from '../interface';
declare const type: ExecuteRule;
export default type;

 

校驗值的型別,可能的型別有:integer、float、array、regexp、object、method、email、number、data、url、hex

range.d.ts

import { ExecuteRule } from '../interface';
declare const range: ExecuteRule;
export default range;

 

校驗是否滿足最大最小值合理區間的規則

whitespace.d.ts

import { ExecuteRule } from '../interface';
/**
 *  Rule for validating whitespace.
 *
 *  @param rule The validation rule.
 *  @param value The value of the field on the source object.
 *  @param source The source object being validated.
 *  @param errors An array of errors that this rule may add
 *  validation errors to.
 *  @param options The validation options.
 *  @param options.messages The validation messages.
 */
declare const whitespace: ExecuteRule;
export default whitespace;

 

校驗空白字元的規則

enum.d.ts

import { ExecuteRule } from '../interface';
declare const enumerable: ExecuteRule;
export default enumerable;

 

校驗值是否存在列舉值列表中的規則

pattern.d.ts

import { ExecuteRule } from '../interface';
declare const pattern: ExecuteRule;
export default pattern;

 

校驗正規表示式的規則

二、rule 應用

interface.d.ts 中定義 rule 單元格式

export interface RuleItem {
 type?: RuleType; //型別
 required?: boolean; //是否為空
 pattern?: RegExp | string; //正則
 min?: number; // 最小值或長度
 max?: number; //最大值或長度
 len?: number; // 長度
 enum?: Array<string | number | boolean | null | undefined>; //校驗值是否存在列舉值列表中的規則
 whitespace?: boolean; //是否空白
 fields?: Record<string, Rule>;//深度監聽屬性和規則
 options?: ValidateOption;//選項
 defaultField?: Rule; //校驗屬性內部值
 transform?: (value: Value) => Value; //校驗前轉換
 message?: string | ((a?: string) => string);//資訊提示
 //非同步校驗
 asyncValidator?: (rule: InternalRuleItem, value: Value, callback: (error?: string | Error) => void, source: Values, options: ValidateOption) => void | Promise<void>;
 //同步校驗
 validator?: (rule: InternalRuleItem, value: Value, callback: (error?: string | Error) => void, source: Values, options: ValidateOption) => SyncValidateResult | void;
}
// Rule 可以是一個物件,也可以是該物件的陣列 
export declare type Rule = RuleItem | RuleItem[];

 

rule 是本欄位對應的校驗規則:

{
 field: "name",
 fullField: "name",
 message: "姓名為必填項",
 required: false,
 type: "string",
 validator: ƒ required$1(rule, value, callback, source, options)
}

 

value 是本欄位的值:如小明

source 是要校驗的整個 source 物件:

{
 name: '小明',
 info: {
  age: 17,
 }
}

 

errors 是本次校驗將要去新增的 errors 陣列,假設之前沒有 error,則 errors 為[],如果之前已經存在了一些 error,則格式如下所示:

[
 {
  message: '年齡超出範圍',
  field: 'info.age',
 }
]

 

options 是該欄位校驗時的選項,當 message 屬性為預設值時,格式如下:

{
 firstFields: true,
 messages: {
  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"},
  clone: ƒ clone(),
  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"},
  default: "Validation error on field %s",
  enum: "%s must be one of %s",
  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"},
  pattern: {mismatch: "%s value %s does not match pattern %s"},
  required: "%s is required",
  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"},
  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", …},
  whitespace: "%s cannot be empty",
 }
}

 

三、專案開發應用

實際專案開發中驗證規則 rule 的寫法:

const rules = {
 // 深度校驗1
 address: {
  type: 'object',
  required: true,
  fields: {
   //深度校驗street屬性
   street: { type: 'string', required: true },
   city: { type: 'string', required: true },
   zip: {
    type: 'string',
    required: true,
    len: 8,
    message: 'invalid zip',
   },
  },
 },
 //校驗 2 陣列形式
 username: [
  {
   type: 'string',
   required: true,
   whitespace: true,
   transform(value) {
    return value.trim()
   },
   message: '使用者名稱不能為空格',
   // 非同步校驗
   asyncValidator: (rule, value) => {
    return new Promise((resolve, reject) => {
     setTimeout(() => {
      if (value != '') {
        resolve()
       } else {
         reject('error')
       }
      }, 2000)
     })
    },
   },
   {
    type: 'string',
    min: 3,
    max: 20,
    message: '長度 3- 20 位',
   },
  ],
}

 

相關文章