系列文章:
1、async-validator 原始碼學習(一):文件翻譯
2、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 位', }, ], }