vee-validate 是一個輕量級的 vue表單驗證插件。它有不少開箱即用的驗證規則,也支持自定義驗證規則。它是基於模板的,所以它與HTML5驗證API相似且熟悉。能夠驗證HTML5輸入以及自定義Vue組件。html
項目地址:vee-validatevue
官方文檔:VeeValidatenode
# 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>
這裏使用的是ES6/ES2015語法。ES2015語法是從ES5的一次巨大飛躍,它給JavaScript增長了大量的功能特性。ios
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目錄下拷貝到項目中的中文語言包。git
<script src="path/to/vue.js"></script> <script src="path/to/vee-validate.js"></script> <script> Vue.use(VeeValidate); // good to go. </script>
只須要將 v-validate 指令添加到要驗證的輸入中,並確保輸入中包含生成錯誤消息的 name 屬性。而後,向指令傳遞一個 rules 字符串,其中包含由管道 ‘|’ 分隔的驗證規則列表。github
<input v-validate="'required|email'" name="email" type="text">
在上面示例中, required 代表該字段是必須的,email 則表示該字段必須爲電子郵件。所以使用結合這兩個規則,聲明字符串變量 required|email 給 v-validate 表達式的值。npm
若是要顯示錯誤信息,只需使用 errors.first 方法獲取該字段生成的第一個錯誤:axios
<span>{{ errors.first('email') }}</span>
可是須要注意:客戶端驗證永遠不能替代服務器驗證,確保在後端驗證用戶的任何輸入。後端
提醒:錯誤信息裏面的名稱一般就是表單的name屬性,除非是經過Vue實例傳遞進去的。數組
提醒:養成習慣,給每一個field添加 name 屬性,若是沒有 name 屬性又沒有對值進行綁定的話,validator 可能不會對其進行正確校驗。
errors是組件內置的一個數據模型,用來存儲和處理錯誤信息。默認狀況下,錯誤包實例將注入組件 errors 名稱下的計算屬性中,能夠對其進行自定義以免與其餘 庫/組件 發送衝突。
但願一次爲字段顯示一個錯誤,使用 errors.first('fieldName') 方法執行此操做。
<input type="text" name="fieldName" v-validate="'required'"> <span>{{ errors.first('fieldName') }}</span>
VeeValidate 默認每一個字段僅生成一條消息,由於它在運行驗證管道時使用快速退出策略。當檢測到第一個失敗規則時,它將生成消息並將其存儲在錯誤包實例中,而後忽略其餘規則結果。
要禁用此行爲,須要 fastExit 在 VeeValidate的配置中 配置選項或使用 continues 修飾符。
一般應用場景是容許用戶一次修復多個輸入錯誤。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>
若是須要在表單上顯示全部字段錯誤,尤爲是很是大的表單。
可使用 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>
使用 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>
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
<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 值而不是實際的字段名稱。
這樣對於簡單設置和顯示本地化名稱很是有用,但僅適用於單一語言環境頁面。
const validator = (value, args) => { // Return a Boolean or a Promise. } //最基本的形式,只返回布爾值或者Promise,帶默認的錯誤提示
const validator = { getMessage(field, args) { // 添加到默認的英文錯誤消息裏面 // Returns a message. }, validate(value, args) { // Returns a Boolean or a Promise. } };
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>
import { Validator } from 'vee-validate'; const dictionary = { en: { messages: { alpha: () => 'Some English Message' } }, cn: { messages: { alpha: () => '對alpha規則的錯誤定義中文描述' } } }; Validator.updateDictionary(dictionary);
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);
針對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; } } });