async-validator 是一個表單非同步校驗庫,阿里旗下的 Ant-design 和 Element 元件庫中的表單驗證使用的都是 async-validator ,目前版本已更新到 4.0.7 ,下載量達到 1,067,202次,不僅支援 js ,同時也可支援 typeScript 。是一個功能超級強大的庫,有興趣的一起來了解了解。
async-validator 官網地址:
https://www.npmjs.com/package/async-validator
async-validator 美中不足的是沒有中文官方文件,看著英文的好費勁!網上百度了一堆都是低版本的翻譯,現在升級到 4.0.7 了,有些效能廢棄了,會出現一些不起作用的屬性,所以今天幫大家也幫自己翻譯一下,便於學習。
一、從入門到上手
安裝命令
npm i async-validator // 或 npm install async-validator
使用方法:
// 引入非同步 import Schema from 'async-validator' // 定義規則描述 const des = { name: { type: "string", required: true, message: "內容不能為空" } } // 建立校驗器 const validator = new Schema(des) // 新增校驗 validator.validate({ name: "值" }, (errors, field) => { if(errors){ return new Error(`校驗失敗`) } // 校驗失敗 })
在 vue3 引入 Ant-design 元件中使用 async-validator ,使用例項:
<template> <div> <a-form style="width: 80%; margin: 0 auto;" :model="formData"> <div> 使用者名稱: <a-input type="text" @blur="check" v-model:value="formData.username"></a-input> </div> <div> 密碼: <a-input type="passsword" v-model:value="formData.password"></a-input> </div> <a-button type="primary">提交</a-button> </a-form> </div> </template> <script lang="ts"> import { defineComponent, reactive, onMounted } from 'vue' import Schema from 'async-validator' interface IFormData { username: string password: string } export default defineComponent({ setup() { const formData = reactive<IFormData>({ username: '', password: '', }) const des = { username: [ { type: 'string', required: true, validator(rule, value) { return value != '' } message: '使用者名稱不能為空', }, { type: 'string', min: 6, max: 10, validator(rule, value) { return rule.min < value.length && value.length < rule.max }, message: '長度 6-8', }, ], } const validator = new Schema(des) function check() { // 開始校驗 validator.validate({ username: formData.username }, (errors, fields) => { if (errors) { return new Error(`不符合規則`) } console.log('校驗成功') }).then((res) => { console.log('res--->', res) }) } return { formData, changeName, } } }) </script>
Promise 使用方法
// 引入非同步 import Schema from 'async-validator' // 定義規則描述 const des = { name: { type: "string", required: true, message: "內容不能為空", asyncValidator: (rule,value) => { // @rule 獲取到是此處限制規則 // @value 獲取到屬性 name 的值 return new Promise((resolve,reject) => { setTimeout(()=>{ // 使用定時器模擬非同步操作 if(value != ""){ resolve() //成功 }else{ reject("校驗失敗") } },2000) }) } } } // 建立校驗器 const validator = new Schema(des) // 新增校驗 validator.validate({ name: "值" }, (errors, field) => { }).then(() => { console.log('校驗成功') }).catch(({ errors, fields } => { console.log('校驗失敗', errors) }))
使用方法挺簡單的,可以根據上述的例項進行簡單修改就可以實現,也可以自己動手試試!
二、API 學習
2.1、validate
validate:新增校驗的方法,使用語法:
validator.validate( source , [options], callback ): Promise
- source 是需要校驗的屬性和值,必傳引數。
- options 是描述處理驗證物件的選項。
- callback 校驗完成之後的回撥函式。
該方法返回的是 Promise 物件,所以有:
- then() 成功回撥
- catch(({ errors, fields })=>{}) 失敗回撥
Options 選項引數有:
- suppressWarning:是一個 Boolean 值,是否抑制無效的內部警告。
- first:是一個 Boolean 值,當第一個校驗失敗時,是否繼續向後校驗,如果為真,只返回第一個校驗失敗資訊。
- firstFields:是一個 Boolean 值或 字串陣列,當指定的第一個校驗規則生成錯誤時呼叫回撥,不再處理同一欄位的驗證規則,true 表示所有欄位。
2.2、Rules
rules :表示校驗規則,通常有兩種寫法:
第一種:經常寫成一個物件陣列,便於給單個欄位新增多個驗證規則。使用如下:
const descriptor = { name:[ { type: 'string', required: true, validator(rule, value) { return value != '' } message: '使用者名稱不能為空', }, { type: 'string', min: 3, max: 8, validator(rule, value) { return rule.min < value.length && value.length < rule.max }, message: '使用者名稱長度 3-8', }, ] }
第二種:也可以定義成執行驗證的函式,使用語法:
function (rule, value, callback, source, options)
- rule 是源描述符中與正在驗證的欄位名相對應的驗證規則,始終會為其分配一個欄位屬性,該屬性包含要驗證的欄位名稱
- value 是校驗屬性的值。
- callback 呼叫完成後呼叫的回撥函式。
- source 校驗的源物件。
- options 其他選項。
傳遞給 validate 或 asyncValidate 的選項將傳遞給驗證函式,以便您可以在驗證函式中引用瞬態資料(例如模型引用)。但是,保留了一些選項名稱;如果使用選項物件的這些屬性,它們將被覆蓋。保留屬性包括訊息、異常和錯誤。
2.3、Type
type :指示要校驗的屬性型別,它的型別值有:
- string - 預設值,屬性型別必須是字串。
- number - 必須是數字。
- boolean - 是布林值。
- regexp - 是一個 RegExp 例項或 new RegExp 時不生成異常字串
- method - 必須是一個函式。
- integer - 必須是數字和整數型別。
- float - 必須是數字和浮點數。
- array - 是陣列,使用 Array.isArray 驗證。
- object - 是一個物件而且不是陣列物件。
- enum - 值必須存在於列舉中。
- date - 值必須是由日期確定的有效值。
- url - 是一個 url 型別。
- hex - 十六進位制。
- email - 必須是 email 型別。
- any - 可以為任意型別。
2.4、Required
required 屬性代表源物件上必須存在該欄位。
2.5、Pattern
rule 屬性指示必須匹配正規表示式。
2.6、Range
通過使用 min(最小) 和 max(最大) 屬性定義一個範圍,對應字串和陣列會與 length 比較,對於數字會直接拿值比較。
2.7、Length
會使用 len 屬性定義長度,對應字串和陣列會與 length 比較,數字會直接拿值進行比較。如果 min、max 和 len 同時出現時,len 優先使用。
2.9、Enumerable
enumerable 可列舉值。對於可以列舉出所有情況的型別,可使用列舉校驗,如:
var descriptor = { role: {type: "enum", enum: ['admin', 'user', 'guest']} }
2.10、Whitespace
通常將僅包含空格的必填欄位視為錯誤。要為僅由空格組成的字串新增附加測試,請將whitespace屬性新增到值為true. 規則必須是string型別。
您可能希望清理使用者輸入而不是測試空格,請參閱 transform 以獲取允許您去除空格的示例。
個人使用 whitespace 之後,感覺沒有任何影響,官方講的也很簡單,未找到具體例項,如果有會用的,還請不吝賜教。
2.11、Deep Rules
如果需要校驗的資料型別是物件,且需要校驗物件中的每一個屬性,此時需要通過巢狀規則分配給 rules 的 fields 屬性來校驗屬於 object 或 array 型別的校驗規則。
對 object 的深度監聽:
const rules = { address: { type: 'object', required: true, fields: { street: { type: 'string', required: true }, city: { type: 'string', required: true } } } }
注意:如果在父規則上沒有指定 required 屬性,此時沒有在源物件上宣告的欄位也是有效的,但是深度監聽會失效。
對 array 的深度監聽:
const 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'] } 這樣的 source 物件,將建立兩個錯誤。一個用於陣列長度不匹配,另一個用於缺少索引 2 處所需的陣列。
2.12、defaultField
defaultField 屬性用來校驗內部的所有值,可以用於 array 或 object 型別。
const descriptor = { urls: { type: 'array', required: true, defaultField: { type: 'url' }, } };
注意,若將 defaultField 擴充套件為fields,請參見 deep rules。
2.13、transform
有時校驗之前需要進行某種處理或者轉化,因此在校驗規則中新增 transform 函式,在校驗之前對屬性進行某種轉換,並重新分配給源物件以更改屬性的值。
const rules = { username: { type: 'string', required: true, pattern: /^[a-z]+$/, transform(value) { return value.trim(); }, }, } const validator = new Schema(rules) const source = { username: ' user ' }; validator.validate(source).then(() => assert.equal(source.name, 'user'));
transform 函式內的 value.trim() 會把傳入的值前後空格去掉,所以校驗成功,如果沒有 transfrom 函式,校驗將會失敗。
2.14、message
根據應用的需求,可能需要 i18n 支援,或者您可能更喜歡不同的驗證錯誤訊息。
最簡單的方法給 rule 分配一條 message 屬性:
const rules = { username: { type: 'string', required: true, message:"使用者名稱不能為空" } }
message 可以是任意型別,如 jsx 格式:
const rules = { username: { type: 'string', required: true, message:"<b>使用者名稱不能為空</b>" }, }
message 也可以是一個函式,比如 vue-i18n :
{ name: { type: 'string', required: true, message: () => this.$t( '請填寫名稱' ) } }
不同語言可能需要相同的模式驗證規則,在這種情況下,為每種語言複製模式規則是沒有意義的。
在這種情況下,您可以為該語言提供自己的訊息,並將其分配給 shema:
import Schema from 'async-validator'; const cn = { required: '%s 必填', }; const descriptor = { name: { type: 'string', required: true } }; const validator = new Schema(descriptor); // deep merge with defaultMessages validator.messages(cn);
如果要定義自己的驗證函式,最好將訊息字串指定給messages物件,然後通過選項訪問訊息。驗證函式中的messages屬性。
2.15、asyncValidator
為指定欄位自定義非同步校驗函式:
const rules = { 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) }) }, ], } const validator = new Schema(rules) const source = { username: ' user ' }; validator.validate(source).then((res) => { console.log('res', res) }) .catch(({ errors, fields }) => { console.log('err', errors) console.log('fields', fields) })
2.16、validator
為指定欄位自定義同步校驗函式:
const rules = { username: [ { type: 'string', required: true, validator(rule, value) { return value != '' }, message: '使用者名稱不能為空', }, { type: 'string', min: 6, max: 10, validator(rule, value) { return rule.min < value.length && value.length < rule.max }, message: '長度 6-8', }, ], }
常見問題
如何取消 warning
import Schema from 'async-validator'; Schema.warning = function () {};
如果檢查布林值true
使用 enum 型別 並傳佈爾值 true 引數作為選項。
{ type: 'enum', enum: [true], message: '', }
測試用例
npm test
測試覆蓋率
npm run coverage