async-validator 源碼學習(一):文檔翻譯


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


免責聲明!

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



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