一、vee-validate入門
vee-validate 是一個輕量級的 vue表單驗證插件。它有很多開箱即用的驗證規則,也支持自定義驗證規則。它是基於模板的,因此它與HTML5驗證API類似且熟悉。可以驗證HTML5輸入以及自定義Vue組件。
項目地址:vee-validate
官方文檔:VeeValidate
1、安裝
# NPM安裝 $ npm install vee-validate --save # CDN安裝 <!-- jsdelivr cdn --> <script src="https://cdn.jsdelivr.net/npm/vee-validate@latest/dist/vee-validate.js"></script> <!-- unpkg --> <script src="https://unpkg.com/vee-validate@latest"></script>
2、引用
(1)方法一:在main.js中添加
這里使用的是ES6/ES2015語法。ES2015語法是從ES5的一次巨大飛躍,它給JavaScript增加了大量的功能特性。
import Vue from 'vue' import axios from 'axios' import VeeValidate, {Validator} from 'vee-validate'; import veeMessage from 'vee-validate/dist/locale/zh_CN'; // 添加表單驗證 Vue.use(VeeValidate, { classes: true, classNames: { valid: 'is-valid', invalid: 'is-invalid' } }); // 使用中文提示 Validator.localize('zh_CN', veeMessage);
zh_CN是從 node_module/vee-validate/dist/locale目錄下拷貝到項目中的中文語言包。
(2)方法二:直接包含腳本
<script src="path/to/vue.js"></script> <script src="path/to/vee-validate.js"></script> <script> Vue.use(VeeValidate); // good to go. </script>
3、基本使用
只需要將 v-validate 指令添加到要驗證的輸入中,並確保輸入中包含生成錯誤消息的 name 屬性。然后,向指令傳遞一個 rules 字符串,其中包含由管道 ‘|’ 分隔的驗證規則列表。
<input v-validate="'required|email'" name="email" type="text">
在上面示例中, required 表明該字段是必須的,email 則表示該字段必須為電子郵件。因此使用結合這兩個規則,聲明字符串變量 required|email 給 v-validate 表達式的值。
如果要顯示錯誤信息,只需使用 errors.first 方法獲取該字段生成的第一個錯誤:
<span>{{ errors.first('email') }}</span>
但是需要注意:客戶端驗證永遠不能替代服務器驗證,確保在后端驗證用戶的任何輸入。
提醒:錯誤信息里面的名稱通常就是表單的name屬性,除非是通過Vue實例傳遞進去的。
提醒:養成習慣,給每個field添加 name 屬性,如果沒有 name 屬性又沒有對值進行綁定的話,validator 可能不會對其進行正確校驗。
二、顯示錯誤
errors是組件內置的一個數據模型,用來存儲和處理錯誤信息。默認情況下,錯誤包實例將注入組件 errors 名稱下的計算屬性中,可以對其進行自定義以避免與其他 庫/組件 發送沖突。
1、顯示單個錯誤消息
希望一次為字段顯示一個錯誤,使用 errors.first('fieldName') 方法執行此操作。
<input type="text" name="fieldName" v-validate="'required'"> <span>{{ errors.first('fieldName') }}</span>
VeeValidate 默認每個字段僅生成一條消息,因為它在運行驗證管道時使用快速退出策略。當檢測到第一個失敗規則時,它將生成消息並將其存儲在錯誤包實例中,然后忽略其他規則結果。
要禁用此行為,需要 fastExit 在 VeeValidate的配置中 配置選項或使用 continues 修飾符。
2、顯示多條錯誤消息
通常應用場景是允許用戶一次修復多個輸入錯誤。errors.collect('fieldName') 方法可以將特定字段的所有錯誤消息收集到數組中。
<input type="text" name="fieldName" v-validate.continues="'required|alpha|min:5'"> <ul> <li v-for="error in errors.collect('fieldName')">{{ error }}</li> </ul>
3、顯示所有錯誤
如果需要在表單上顯示所有字段錯誤,尤其是非常大的表單。
(1)錯誤列表
可以使用 errors.all() 將所有字段錯誤收集到單個平面數組中。
<input type="text" name="first" v-validate.continues="'required|alpha|min:5'"> <input type="text" name="second" v-validate.continues="'required|alpha|min:5'"> <ul> <li v-for="error in errors.all()">{{ error }}</li> </ul>
(2)按字段名稱分組
使用 erros.collect() 按字段名稱對錯誤消息進行分組,其中鍵是字段名稱,值是每個字段的錯誤消息數組:
<input type="text" name="first" v-validate.continues="'required|alpha|min:5'"> <input type="text" name="second" v-validate.continues="'required|alpha|min:5'"> <ul> <li v-for="group in errors.collect()"> <ul> <li v-for="error in group">{{ error }}</li> </ul> </li> </ul>
三、內置的驗證規則
1、內置驗證規則匯總
after{target} - 比target要大的一個合法日期,格式(DD/MM/YYYY) alpha - 只包含英文字符 alpha_dash - 可以包含英文、數字、下划線、破折號 alpha_num - 可以包含英文和數字 before:{target} - 和after相反 between:{min},{max} - 在min和max之間的數字 confirmed:{target} - 必須和target一樣 date_between:{min,max} - 日期在min和max之間 date_format:{format} - 合法的format格式化日期 decimal:{decimals?} - 數字,而且是decimals進制 digits:{length} - 長度為length的數字 dimensions:{width},{height} - 符合寬高規定的圖片 email - 不解釋 ext:[extensions] - 后綴名 image - 圖片 in:[list] - 包含在數組list內的值 ip - ipv4地址 max:{length} - 最大長度為length的字符 mimes:[list] - 文件類型 min - max相反 mot_in - in相反 numeric - 只允許數字 regex:{pattern} - 值必須符合正則pattern required - 不解釋 size:{kb} - 文件大小不超過 url:{domain?} - (指定域名的)url
2、內置規則使用示例
<input type="text" class="form-control" id="tel" v-model="queryInfo.tel" placeholder="手機號碼" v-validate="'min:11|max:11|numeric'" name="tel" data-vv-as="手機號碼"> <input type="text" class="form-control" id="idNum" v-model="queryInfo.idNumCipher" placeholder="身份證號" v-validate="'required|max:18|min:18|alpha_num'" name="idNum" data-vv-as="身份證號"> <input type="text" class="form-control" id="emailnum" v-model="queryInfo.email" placeholder="電子郵箱" v-validate="'email'" name="emailnum" data-vv-as="電子郵箱">
如果使用了 data-vv-as 屬性,在輸入生成任何錯誤消息時,它將使用 data-vv-as 值而不是實際的字段名稱。
這樣對於簡單設置和顯示本地化名稱非常有用,但僅適用於單一語言環境頁面。
四、自定義驗證規則
1、直接定義
const validator = (value, args) => { // Return a Boolean or a Promise. } //最基本的形式,只返回布爾值或者Promise,帶默認的錯誤提示
2、對象形式
const validator = { getMessage(field, args) { // 添加到默認的英文錯誤消息里面 // Returns a message. }, validate(value, args) { // Returns a Boolean or a Promise. } };
3、添加到指定語言的錯誤消息
const validator = { messages: { en: (field, args) => { // 英文錯誤提示 }, cn: (field, args) => { // 中文錯誤提示 } }, validate(value, args) { // Returns a Boolean or a Promise. } };
創建了規則之后,用extend方法添加到Validator里:
import { Validator } from 'vee-validate'; const isMobile = { messages: { en:(field, args) => field + '必須是11位手機號碼', }, validate: (value, args) => { return value.length == 11 && /^((13|14|15|17|18)[0-9]{1}\d{8})$/.test(value) } } Validator.extend('mobile', isMobile); //或者直接 Validator.extend('mobile', { messages: { en:field => field + '必須是11位手機號碼', }, validate: value => { return value.length == 11 && /^((13|14|15|17|18)[0-9]{1}\d{8})$/.test(value) } });
然后可以直接把mobile當成內置規則使用:
<input v-validate data-rules="required|mobile" :class="{'input': true, 'is-danger': errors.has('mobile') }" name="mobile" type="text" placeholder="Mobile"> <span v-show="errors.has('mobile')" class="help is-danger">{{ errors.first('mobile') }}</span>
4、自定義內置規則的錯誤信息
import { Validator } from 'vee-validate'; const dictionary = { en: { messages: { alpha: () => 'Some English Message' } }, cn: { messages: { alpha: () => '對alpha規則的錯誤定義中文描述' } } }; Validator.updateDictionary(dictionary);
5、常用自定義規則
Validator.localize('zh_CN', veeMessage); // 自定義身份證號碼驗證 Validator.extend('idCardNum', { getMessage: field => '請輸入正確的身份證號碼', // 身份證號碼為15位或者18位,15位時全為數字,18位前17位為數字,最后一位是校驗位,可能為數字或字符X validate: value => /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value) }); // 自定義手機號碼驗證 Validator.extend('mobile', { // extend的第一個參數就是自定義的規則的名字 getMessage: field => '請輸入正確的手機號碼', // getMessage中是錯誤提示信息 validate: value => value.length === 11 && /^((13|14|15|17|18)[0-9]{1}\d{8})$/.test(value) // validate是驗證規則,返回一個布爾值或promise }); // 自定義敏感詞過濾 const sensitiveWordRule = { getMessage: (field, args) => field + '敏感字段', validate: (value, args) => { let sensitiveMap = makeSensitiveMap(sensitiveWordList); console.log('sensitivemap', sensitiveMap); if (checkSensitiveWord(sensitiveMap, value).length > 0) { console.log(checkSensitiveWord(sensitiveMap, value)) return false; } else { console.log(checkSensitiveWord(sensitiveMap, value)) return true; } } }; Validator.extend('sensitiveWordFilter', sensitiveWordRule);
6、與相關組件配合驗證
針對Enums和Select(src/components/chart/Select2.vue)驗證:
// 自定義 Enmus 驗證 Validator.extend('enums', { // extend的第一個參數就是自定義的規則的名字 validate: value => value > 0 && value != null && value != undefined // validate是驗證規則,返回一個布爾值或promise }); // 自定義 Select2 驗證 Validator.extend('select2', { // extend的第一個參數就是自定義的規則的名字 getMessage: field => field + '不能為空', validate: value => value > 0 && value != null && value != undefined // validate是驗證規則,返回一個布爾值或promise });
針對 Datepicker 驗證:
// 自定義時間區間選擇組件 Datepicker 驗證 -- 起止時間驗證 Validator.extend('datepickerwrongrange', { getMessage: field => '起止時間不能相等', validate: function (value) { var d = value.split('-'); var beginTime = parseInt(d[0]); var endTime = parseInt(d[1]); if(beginTime == endTime) { return false; } else { return true; } } }); // 自定義時間區間選擇組件 Datepicker 驗證 -- 開始時間驗證 Validator.extend('datepickerwrongbegin', { getMessage: field => '開始時間不能小於當前時間后的一小時', validate: function (value) { var d = value.split('-'); var beginTime = parseInt(d[0]); var endTime = parseInt(d[1]); if(beginTime <= (Date.parse(new Date()) + 3600*1000)) { return false; } else { return true; } } });