async-validator 的中文文檔翻譯


阿里出品的 antd 和 ElementUI 組件庫中表單校驗默認使用的 async-validator,它在 gitbub 上也獲得了 3.8k 的 star,可見這個庫十分強大,奈何只有英文文檔看的蛋疼,因此花點時間翻譯一下以便日后查看和為新手同事提供文檔,原文都以折疊的方式保留着,看不懂我的描述可以展開看看原文。

結合 github 上的例子能方便理解

(大部分原因是我英文水平不夠,但是明明是中國人寫的為啥不順手寫個中文的 readme 呢,雖然就算翻譯成了中文也還是晦澀難懂。。。)

正文開始。


async-validator

一個用於表單異步校驗的庫,參考了 https://github.com/freeformsystems/async-validate

API

下述內容來自於 async-validate. 的早期版本

Usage 使用方法

基本的使用方法:定義一個 descriptor,將它傳入 schema,得到一個 validator。將需要校驗的對象和回調傳入 validator.validate 方法中。

注:descriptor 是對校驗規則的描述,validator 是根據校驗規則得到的校驗器

var schema = require('async-validator'); var descriptor = { name: { type: "string", required: true, validator: (rule, value) => value === 'muji', }, }; var validator = new schema(descriptor); validator.validate({name: "muji"}, (errors, fields) => { if(errors) { // validation failed, errors is an array of all errors // fields is an object keyed by field name with an array of // errors per field // 校驗未通過的情況,errors 是所有錯誤的數組 // fields 是一個 object,以字段作為 key 值,該字段對應的錯誤數組作為 value // (其實 fields 就是把 errors 按照原對象的 key 值分組) return handleErrors(errors, fields); } // validation passed // 這里說明校驗已通過 }); // PROMISE USAGE // Promise 式用法 validator.validate({ name: "muji", asyncValidator: (rule, value) => axios.post('/nameValidator', { name: value }), }, (errors, fields) => { if(errors) { // validation failed, errors is an array of all errors // fields is an object keyed by field name with an array of // errors per field // 校驗未通過的情況,errors 和 fields 同上 return handleErrors(errors, fields); } // validation passed // 校驗通過 }) .then(() => { // validation passed // 校驗通過 }) .catch(({ errors, fields }) => { return handleErrors(errors, fields); }) 

Validate 方法參數

function(source, [options], callback): Promise 
  • source: 需要校驗的對象(必填).
  • options: 校驗選項(可選).
  • callback: 校驗完成時的回調(必填).

方法返回一個 Promise 對象:

  • then(),說明校驗通過
  • catch({ errors, fields }),校驗未通過,errors, fields 含義見前面示例

Options 選項

  • first: Boolean, 遇見第一個未通過校驗的值時便調用 callback 回調,不再繼續校驗剩余規則。
    適用情況:校驗涉及到多個異步調用,比如數據庫查詢,而你只需要獲取首個校驗錯誤時

  • firstFields: Boolean|String[], 對於指定字段,遇見第一條未通過的校驗規則時便調用 callback 回調,而不再校驗該字段的其他規則 ,傳入 true 代表所有字段。

Rules

Rules 也可以是用於校驗的函數

function(rule, value, callback, source, options) 
  • rule: 當前校驗字段在 descriptor 中所對應的校驗規則,其中的 field 屬性是當前正在校驗字段的名稱
  • value: 當前校驗字段的值
  • callback: 在校驗完成時的回調,傳入 Error [或者是一個數組] 代表校驗失敗,如果校驗是同步的話,直接返回 false 或 Error 或 Error 數組也可以(注:異步校驗通過時直接不帶參數調用 callback(),代表沒有錯誤)
  • source: 傳入 validate 方法的 object,也就是需要校驗的對象
  • options: 傳入的額外選項
  • options.messages: 對象包含的校驗錯誤提示信息,會被合並到默認的提示信息中

傳入 validate 或 asyncValidate 的 options 被帶到了校驗函數中,以便你可以在校驗函數中拿到數據(比如 model 引用)。然而,option中部分屬性名是被保留的,你如果使用了的話會被覆蓋掉,其中包括 messagesexception 和 error

var schema = require('async-validator'); var descriptor = { name(rule, value, callback, source, options) { var errors = []; if(!/^[a-z0-9]+$/.test(value)) { errors.push( new Error( util.format("%s must be lowercase alphanumeric characters", rule.field))); } return errors; } } var validator = new schema(descriptor); validator.validate({name: "Firstname"}, (errors, fields) => { if(errors) { return handleErrors(errors, fields); } // validation passed }); 

在需要對一個字段設置多條校驗規則時,可以把規則設為一個數組,比如

var descriptor = { email: [ {type: "string", required: true, pattern: schema.pattern.email}, {validator(rule, value, callback, source, options) { var errors = []; // test if email address already exists in a database // and add a validation error to the errors array if it does return errors; }} ] } 

Type 內置類型

下列是 type 可用的值:

  • string: 必須是 stringThis is the default type.
  • number: 必須是 number.
  • boolean: 必須是 boolean.
  • method: 必須是 function.
  • regexp: 必須是正則或者是在調用 new RegExp 時不報錯的字符串.
  • integer: 整數.
  • float: 浮點數.
  • array: 必須是數組,通過 Array.isArray 判斷.
  • object: 是對象且不為數組.
  • enum: 值必須出現在 enmu 枚舉值中.
  • date: 合法的日期,使用 Date 判斷
  • url: url.
  • hex: 16進制.
  • email: 郵箱地址.

Required

required 屬性代表這個字段必須出現在對象中

Pattern

pattern 屬性代表需要符合的正則

Range

使用 min 和 max 屬性定義范圍,對於字符串和數組會與 value.length 比較,對於數字會直接與值比較

Length

使用 len 屬性直接指定長度,會與字符串和數組的 value.length 比較相等,對於數字會直接與值比較是否相等
如果 len 與 min 和 max 同時使用, len 優先。

Enumerable

可枚舉值

對於可以枚舉出所有情況的類型,可以使用枚舉校驗,如下:

var descriptor = { role: {type: "enum", enum: ['admin', 'user', 'guest']} } 

Whitespace

把僅包含空格的字段視為錯誤是很典型的做法,為了額外測試字段是否只有空格,添加 whitespace 屬性並設為true。這個屬性要求字段必須為 string 類型。

如果你想要修正用戶的輸入而不是測試有無空格,查看 transform 中去除空格的例子。

Deep Rules 深層規則

如果需要校驗一個深層的對象,你需要使用 fields 屬性來設置嵌套的規則

var descriptor = { address: { type: "object", required: true, fields: { street: {type: "string", required: true}, city: {type: "string", required: true}, zip: {type: "string", required: true, len: 8, message: "invalid zip"} } }, name: {type: "string", required: true} } var validator = new schema(descriptor); validator.validate({ address: {} }, (errors, fields) => { // errors for address.street, address.city, address.zip }); 

需要注意的是,如果沒有在父規則上指定 required 屬性,在校驗對象中不存在這個屬性是完全合法的,嵌套的深層規則也不會運行。

深層規則提供了直接一個定義嵌套規則的方式,讓你可以簡化傳遞給 schema.validate() 的 options 。

var descriptor = { address: { type: "object", required: true, options: {single: true, first: true}, fields: { street: {type: "string", required: true}, city: {type: "string", required: true}, zip: {type: "string", required: true, len: 8, message: "invalid zip"} } }, name: {type: "string", required: true} } var validator = new schema(descriptor); validator.validate({ address: {} }) .catch(({ errors, fields }) => { // now only errors for street and name }); 

如果你像下面這樣寫,父規則也會被校驗

var descriptor = { roles: { type: "array", required: true, len: 3, fields: { 0: {type: "string", required: true}, 1: {type: "string", required: true}, 2: {type: "string", required: true} } } } 

比如用於 {roles: ["admin", "user"]} 會產生兩個錯誤,一個是數組長度不匹配,一個是缺少了索引為 2 的元素

defaultField 默認字段

defaultField 屬性可以在 array 和 object 類型中用於校驗所有的值,它可以是一個包含有校驗規則的對象或數組。 例子如下:

var descriptor = { urls: { type: "array", required: true, defaultField: {type: "url"} } } 

注意,defaultField 是 fields 的擴展,見 deep rules.

Transform 變換

有時候需要在校驗前修改值,強制修改為特定格式。 為此在校驗規則中添加了 transform, 這個屬性會在校驗前執行,以適當的方式改變原始對象的值。(也就是返回值會作用在原始對象的值上)

var schema = require('async-validator'); var sanitize = require('validator').sanitize; var descriptor = { name: { type: "string", required: true, pattern: /^[a-z]+$/, transform(value) { return sanitize(value).trim(); } } } var validator = new schema(descriptor); var source = {name: " user "}; validator.validate(source) .then(() => assert.equal(source.name, "user")); 

如果沒有 transform 函數校驗會失敗因為前后空格導致正則與輸入不符,但在添加了 transform 函數后便可通過因為字段已經被清洗了(或者翻譯為使輸入值符合預期格式)

Messages 提示信息

在某些需求下,你可能需要格式化支持或者想要不同校驗錯誤信息。

最簡單的方式就是直接為 message 屬性賦值:

{name:{type: "string", required: true, message: "Name is required"}} 

消息可以是任意類型的,比如 JSX

{name:{type: "string", required: true, message: <b>Name is required</b>}} 

也可以是函數,比如使用 vue-i18n 時:

{name:{type: "string", required: true, message: () => this.$t( 'name is required' )}} 

有時候你只是需要對相同的校驗規則定義不同語言的提示信息,在這種情況下為各種語言重復定義信息就顯得很多余。

你也可以采取這個方案:定義你自己的提示信息並賦值給 schema :

var schema = require('async-validator'); var cn = { required: '%s 必填', }; var descriptor = {name:{type: "string", required: true}}; var validator = new schema(descriptor); // deep merge with defaultMessages validator.messages(cn); ... 

如果你要定義自己的校驗函數,最好將提示信息賦值給消息對象,並在校驗函數中通過 options.messages 訪問消息。(說實話我沒看懂是什么意思,應該是指不要把消息硬編碼寫在校驗函數里面而是通過option傳遞,以便修改)

asyncValidator 異步校驗函數

你可以對指定的字段自定義包含異步操作的校驗函數

const fields = { asyncField:{ asyncValidator(rule,value,callback){ ajax({ url:'xx', value:value }).then(function(data){ callback(); },function(error){ callback(new Error(error)) }); } }, promiseField:{ asyncValidator(rule, value){ return ajax({ url:'xx', value:value }); } } }; 

validator 校驗函數

你也可像下面這樣自定義校驗函數:

const fields = { field:{ validator(rule,value,callback){ return value === 'test'; }, message: 'Value is not equal to "test".', }, field2:{ validator(rule,value,callback){ return new Error(`'${value} is not equal to "test".'`); }, }, arrField:{ validator(rule, value){ return [ new Error('Message 1'), new Error('Message 2'), ]; } }, }; 

FAQ

How to avoid warning 如何關閉警告

var Schema = require('async-validator'); Schema.warning = function(){};



文章就分享到這,歡迎關注“前端大神之路


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM