vue.js基礎知識篇(7):表單校驗詳解


目錄

網盤

第12章:表單校驗

1.npm安裝vue-validator

$ npm install vue-validator

代碼示例:

var Vue=require("vue"); var VueValidator=require("vue-validator"); Vue.use(VueValidator);

2.直接使用script標簽引入vue.js

要下載vue-validator,那么進入cdn的地址https://cdn.bootcss.com/vue-validator/2.1.3/vue-validator.js把內容復制下來就好了。版本使用了2.1.3,不要搞錯了哦。

下面是簡單的小例子。

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm"> <form novalidate> Zip: <input type="text" v-validate:zip="['required']"><br /> <div> <span v-if="$myForm.zip.required">Zip code is required.</span> </div> </form> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> new Vue({ el:"#app", }) </script> </body> </html>
復制代碼

將要驗證的表單包裹在validator自定義元素指令中,而在要驗證的表單控件元素的 v-validate 屬性上綁定相應的校驗規則。

驗證結果會保存在組建實例的 $myForm 屬性下。 $myForm 是由 validator 元素和 name 屬性和 $ 前綴組件。

注意哦,這個校驗在2.1.3版本並不依賴v-model指令。

3.驗證結果的結構

使用上面的例子。

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm"> <form novalidate> Zip: <input type="text" v-validate:zip="['required']"><br /> <div> {{$myForm |json}} </div> </form> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> new Vue({ el:"#app", }) </script> </body> </html>
復制代碼

 {{$myForm |json}} 顯示的內容是:

復制代碼
{ "valid": false, "invalid": true, "touched": false, "untouched": true, "modified": false, "dirty": false, "pristine": true, "zip": { //zip字段的驗證結果 "required": true, "modified": false, "pristine": true, "dirty": false, "untouched": true, "touched": false, "invalid": true, "valid": false } }
復制代碼

這些校驗屬性分別是什么意思:

valid:字段校驗是否通過

invalid:取反、

touched:校驗字段所在元素獲得過焦點返回truke,否則返回false

untouched:touched取反

modified:當元素值與初始值是否相同

dirty:字段值改變過至少一次返回true,否則返回false

pristine:dirty取反

表單整體校驗單獨的屬性:

errors:如果整體校驗沒通過,則返回錯誤字段信息數組。否則返回undefined。

 4.驗證器語法

v-validate[:field]="array literal | object literal| bind"

(1)校驗字段名field

vue-validator版本小於2,校驗依賴於v-model指令。2.0之后的版本使用v-validate指令。字段的命名可使用連字符(-),然后通過駝峰式命名法引用它。

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm"> <form novalidate> <h1>1.校驗的字段為user-name,校驗的規則是最小長度6,最大長度12</h1> <input type="text" v-validate:user-name="{minlength:6,maxlength:12}"/> <div> <span v-show="$myForm.userName.minlength">Your comment is too short.</span> <span v-show="$myForm.userName.maxlength">Your comment is too long.</span> </div> </form> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> new Vue({ el:"#app", }) </script> </body> </html>
復制代碼

動態綁定校驗字段:

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm"> <form novalidate> <p v-for="field in fields"> <label :for="field.id">{{field.label}}</label> <!--v-bind:for綁定for屬性的簡寫--> <input type="text" :id="filed.id" :placeholder="field.placeholder" field="{{field.name}}" v-validate="field.validate"/> </p> </form> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> new Vue({ el:"#app", data:{ fields:[ {id:"username",label:"username",name:"username",placeholder:"input your username",validate:{required:true,maxlength:16}} ] } }) </script> </body> </html>
復制代碼

(2)校驗規則定義

第一種,數組字面量。

類似如下代碼:

Zip: <input type="text" v-validate:zip="['required']">

第二種,對象字面量。

類似如下代碼:

<input type="text" v-validate:user-name="{minlength:6,maxlength:12}"/>

對象字面量還可以通過rule字段自定義驗證規則。

<input type="text" v-validate:user-name="{minlength:6,maxlength:{rule:12}"/>

第三種,實例數據屬性。

v-validate的值可以是組件實例的數據屬性,可用來動態綁定檢驗規則。其實就是把校驗的字段換成變量,比較簡單。

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm"> <form novalidate> <h1>1.校驗的字段為id,校驗的規則是最小長度6,最大長度12</h1> <input type="text" v-validate:id="rules"/> <div> <span v-show="$myForm.id.minlength">Your comment is too short.</span> <span v-show="$myForm.id.maxlength">Your comment is too long.</span> </div> </form> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> new Vue({ el:"#app", data:{ rules:{ minlength:3, maxlength:6 } } }) </script> </body> </html>
復制代碼

第四種,與terminal指令(比如v-if、v-for)同時使用。

Vue 通過遞歸遍歷 DOM 樹來編譯模塊。但是當它遇到 terminal 指令時會停止遍歷這個元素的后代元素。這個指令將接管編譯這個元素及其后代元素的任務。v-if 和 v-for 都是 terminal 指令。因為v-validate指令不能與terminal指令同時使用,所以包裹在了div元素中。

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm"> <form novalidate> <h1>1.可以看到,v-if指令包裹在div元素里,並沒有和v-validator指令同時使用</h1> <div class="password"> <label for="password">password:</label> <input id="password" type="password" v-validate:password="['required']"/> <br/> {{$myForm|json}} </div> </form> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> new Vue({ el:"#app", data:{ enable:true } }) </script> </body> </html>
復制代碼

那么如果使用錯誤的代碼:

<div class="password"> <label for="password">password:</label> <input v-if="enable" id="password" type="password" v-validate:password="['required']"/> <br/> {{$myForm|json}} </div>

控制台會報錯

另:可自動校驗通過v-model動態設置的值。

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm"> <form novalidate> Zip: <input type="text" v-model="zip" v-validate:zip="['required']"><br /> <div> 是否錯誤:{{$myForm.zip.required}} </div> </form> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> var vm=new Vue({ el:"#app", data:{ zip:"" } }); setTimeout(function(){ vm.zip="hello world!"; },2000) </script> </body> </html>
復制代碼

顯示結果,等待兩秒之后,我們就看到v-model的值被設置上去,而且根據必填的規則,報錯信息顯示false。

5.內置驗證規則有哪些?

(1)required校驗器適用的元素有input的text、radio、checkbox、number、password、email、tel、url、還有select、textarea。

對應的源碼如下:

復制代碼
function required(val) {
        if (Array.isArray(val)) {
            if (val.length !== 0) {
                var valid = true;
                for (var i = 0, l = val.length; i < l; i++) { valid = required(val[i]); if (!valid) { break; } } return valid; } else { return false; } } else if (typeof val === 'number' || typeof val === 'function') { return true; } else if (typeof val === 'boolean') { return val; } else if (typeof val === 'string') { return val.length > 0; } else if (val !== null && (typeof val === 'undefined' ? 'undefined' : babelHelpers.typeof(val)) === 'object') { return Object.keys(val).length > 0; } else if (val === null || val === undefined) { return false; } }
復制代碼

它是通過typeof判斷各個類型的。

(2)pattern是正則匹配校驗器,適用的元素有text、number、password、email、tel、url類型的input和textarea。

正則匹配的源碼

(3)minlength是最小長度校驗器,適用的元素有text、checkbox、number、password、email、tel、url類型的input和select、textarea。

(4)maxlength是最大長度校驗器,適用的元素有text、checkbox、number、password、email、tel、url類型的input和select、textarea。

(5)min是最小長度校驗器,適用的元素有text、number類型的input和textarea。

(6)max是最小長度校驗器,適用的元素有text、number類型的input和textarea。

6.重置校驗結果

Vue組件實例上調用$resetValidation()方法來動態重置校驗結果。

 

7.checkbox、radio和select的使用例子

checkbox的DEMO:

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm"> <form novalidate> <div>你喜歡哪一種水果?</div> <div> 蘋果:<input id="apple" type="checkbox" value="apple" v-validate:fruits="{ required:{rule:true,message:requiredErrorMsg}, maxlength:{rule:1,message:maxlengthErrorMsg}, minlength:{rule:2,message:minlengthErrorMsg} }"/> </div> <div> 橘子:<input id="orange" type="checkbox" value="orange" v-validate:fruits/> </div> <div> 葡萄:<input id="grape" type="checkbox" value="grape" v-validate:fruits/> </div> <div> 香蕉:<input id="banana" type="checkbox" value="banana" v-validate:fruits /> </div> <div>{{$myForm.fruits.errors|json}}</div> <ul class="errors"> <li v-for="msg in $myForm.fruits.errors"> {{msg.message}} </li> </ul> </form> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> new Vue({ el:"#app", computed:{ requiredErrorMsg:function(){ return "Required fruit!!" }, minlengthErrorMsg:function(){ return "please choose at least 1 fruit!!" }, maxlengthErrorMsg:function(){ return "please choose at most 2 fruits!!" } } }) </script> </body> </html>
復制代碼

單選按鈕的demo:

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm"> <form novalidate> <div>你喜歡哪一種水果?</div> <div> 蘋果:<input id="apple" type="radio" value="apple" v-validate:fruits="{ required:{rule:true,message:requiredErrorMsg} }"/> </div> <div> 橘子:<input id="orange" type="radio" value="orange" v-validate:fruits/> </div> <div> 葡萄:<input id="grape" type="radio" value="grape" v-validate:fruits/> </div> <div> 香蕉:<input id="banana" type="radio" value="banana" v-validate:fruits /> </div> <div>{{$myForm.fruits.errors|json}}</div> <ul class="errors"> <li v-for="msg in $myForm.fruits.errors"> {{msg.message}} </li> </ul> </form> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> new Vue({ el:"#app", computed:{ requiredErrorMsg:function(){ return "Required fruit!!" } } }) </script> </body> </html>
復制代碼

沒有選擇任何選項就會報錯:

下拉列表select的DEMO:

 v-validate指令使用在select標簽上。

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm"> <form novalidate> <select v-validate:city="{required:true}"> <option value="">請選擇你最喜歡的內地城市</option> <option value="beijing">北京</option> <option value="shanghai">上海</option> <option value="chengdu">成都</option> <option value="hangzhou">杭州</option> <option value="suzhou">蘇州</option> <option value="shenzhen">深圳</option> </select> <div v-if="$myForm.city.required"> required </div> </form> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> new Vue({ el:"#app" }) </script> </body> </html>
復制代碼

8.校驗狀態和分組校驗

(1)各校驗狀態對應的class

valid對應的class是valid。

invalid對應的class是invalid。

touched對應的class是touched。

untouched對應的class是untouched。

pristine對應的class是pristine。

dirty對應的class是dirty。

modified對應的class是modified。

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm"> <form novalidate> <input id="username" type="text" v-validate:username="{ required:{rule:true,message:'require your name!'} }"/> </form> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> new Vue({ el:"#app" }) </script> </body> </html>
復制代碼

上面的代碼 <input id="username" type="text" v-validate:username="{ 代碼在頁面初始化之后,會給input添加上一些類名,如下截圖:

(2)自定義校驗狀態class

使用classes屬性,他只能用在validator屬性上或者使用了v-validate的元素上。

<validator name="myForm" :classes="{touched:'touched-validator',dirty:'dirty-validator'">

(3)在v-validate指令的包裹元素使用校驗狀態

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm" :classes="{touched:'touched-validator',dirty:'dirty-validator'}"> <form novalidate> <div v-validate-class class="username"> <input id="username" type="text" v-validate:username="{ required:{rule:true,message:'require your name!'} }"/> </div> </form> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> new Vue({ el:"#app" }) </script> </body> </html>
復制代碼

只是在div上使用了v-validate-class,校驗狀態在頁面初始化之后就可以看到一些類名了。

(4)分組校驗

vue-validator支持分組校驗。如輸入密碼時,可以將第一次輸入密碼與再次輸入密碼的確認放入同一個校驗組內,只有兩次校驗都通過了,該組校驗才算通過。validator元素使用groups屬性,要校驗的input框使用group屬性。

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm" :groups="['passwordGroup']"> <div> password:<input type="password" group="passwordGroup" v-validate:password="{minlength:4,required:true}"/> </div> <div> confirm:<input type="password" group="passwordGroup" v-validate:password-confirm="{minlength:4,required:true}" /> <div>passwordGroup校驗:{{$myForm.passwordGroup.valid}}</div> </div> <!--只有password和confirm都通過校驗,表單的密碼組才會通過校驗--> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> new Vue({ el:"#app" }) </script> </body> </html>
復制代碼

9.validator-errors組件的使用

在之前的例子中使用v-for指令來遍歷輸出錯誤信息。其實vue-validator提供了validator-errors組件能更便捷的輸出錯誤信息的。

使用方法:validator-errros指令,提供動態綁定的validation屬性就好了。

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm"> <form novalidate> <div> username:<input id="username" type="text" v-validate:username="{ required:{rule:true,message:'require your name!'} }"/> </div> <div class="errors"> <validator-errors :validation="$myForm"></validator-errors> </div> </form> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> new Vue({ el:"#app" }) </script> </body> </html>
復制代碼

頁面初始化后的顯示結果:

不喜歡默認的錯誤信息模板,可以自定義。

(1)component模板

除了使用validator-errors指令,動態綁定validation屬性,還要綁定component組件。

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm"> <form novalidate> <div> username:<input id="username" type="text" v-validate:username="{ required:{rule:true,message:'require your name!'} }"/> </div> <div class="errors"> <validator-errors :validation="$myForm" :component="'custom-error'"></validator-errors> </div> </form> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> Vue.component("custom-error",{ props:['field','message'], //這里的屬性可以使用filed,validator,message  template:"<p>{{field}}報錯信息:<span style='color:red;'>{{message}}</span></p>" }) new Vue({ el:"#app" }) </script> </body> </html>
復制代碼

顯示效果為:

(2)partial模板

除了使用validator-errors指令,動態綁定validation屬性,還要提供partial屬性。

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm"> <form novalidate> <div> username:<input id="username" type="text" v-validate:username="{ required:{rule:true,message:'require your name!'} }"/> </div> <div class="errors"> <validator-errors :validation="$myForm" partial="myErrorTemplate"></validator-errors> </div> </form> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> Vue.partial("myErrorTemplate", "<p>報錯信息:<span style='color:red;'>{{message}}</span></p>") new Vue({ el:"#app" }) </script> </body> </html>
復制代碼

10.動態設置錯誤信息

在服務端驗證失敗時,可使用組件實例方法$setValidationErrors動態設置錯誤信息。

類似的偽代碼如下:

復制代碼
new  Vue({
     el:"#app",
     data:{
     },
     methods:{
       onSubmit:function(){
          var self=this;
          var resource=this.$resource("/user/:id");
          resource.save({id:this.id},{
              username:this.username,
              password:this.new
          },function(data,stat,req){
             self.$.setValidationErros();
          }
       }
 }
復制代碼

11.校驗事件

(1)單個字段校驗事件

每個v-validate的所在元素都可以監聽如下事件,無非就是用v-on來幫頂咯。

valid——當字段驗證結果變為有效時觸發。

invalid——當字段驗證結果變為無效時觸發。

touched——當字段失去焦點時觸發。

dirty——當字段首次變化時觸發。

modified——當字段值與初始值不同時或變回初始值時觸發。

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm"> <div> comment:<input type="text" @valid="onValid" v-validate:comment="['required']" </div> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> new Vue({ el:"#app", methods:{ onValid:function(){ console.log("valid事件觸發了"); } } }) </script> </body> </html>
復制代碼

(2)整個表單校驗事件

對validator元素使用v-on綁定。

valid——當字段驗證結果變為有效時觸發。

invalid——當字段驗證結果變為無效時觸發。

touched——當字段失去焦點時觸發。

dirty——當字段首次變化時觸發。

modified——當字段值與初始值不同時或變回初始值時觸發。

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator @valid="onValid" name="myForm"> <div> comment:<input type="text" v-validate:comment="['required']"/> </div> <div> username:<input type="text" v-validate:username="['required']"/> </div> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> new Vue({ el:"#app", methods:{ onValid:function(){ console.log("表單驗證合法"); } } }) </script> </body> </html>
復制代碼

12.異步驗證

(1)注冊異步驗證器

PS:有同學說異步驗證這一塊不是很理解,我解釋一下。傳統的異步驗證使用ajax,當填寫數據的時候,就發送請求告訴你錯誤了或者正確了,常用的場景是驗證碼填寫。因為我這里是純前端代碼,所以異步就直接使用了settimeout來表示了,那么我的demo的思路是如果我的隨機數大於0.5,就是ajax返回校驗成功,否則ajax返回校驗失敗。從前端顯示看,跟真實生產環境的樣子是差不多的,而且我簡化了是console打印。

復制代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <validator name="myForm"> <div> user:<input type="text" v-validate:user="['exist']"/> </div> <p v-show="$validation.user.exist">the user is already registered.</p> </validator> </div> <script src="js/vue.js"></script> <script src="js/vue-validator.js"></script> <script> Vue.validator("exist",function(val){ return function(resolve,reject){ setTimeout(function(){ var r=Math.random(); console.log(r); if(r>0.5){ resolve(); console.log("異步校驗成功"); //異步校驗通過  }else{ reject(); console.log("校驗失敗"); } },500) //返回值為promise對象  } }) new Vue({ el:"#app", methods:{ }, data:{ user:"" } }) </script> </body> </html>
復制代碼

這里的return function等於如下代碼:

復制代碼
var promise=new Promise(function(resolve,reject){ setTimeout(function(){ var r=Math.random(); console.log(r); if(r>0.5){ resolve(); console.log("異步校驗成功"); //異步校驗通過 }else{ reject(); console.log("校驗失敗"); } },500); return promise; });
復制代碼

(2)驗證器函數context

vm屬性。暴露了當前驗證所在的vue實例。

el屬性。暴露了當前驗證器的目標DOM元素。

復制代碼
new Vue({ data(){return {checking:false}); validators:{ phone:function(val){ $(this.el)//暴露了當前驗證器的目標DOM元素  }, exist(val){ this.vm.checking///暴露了當前驗證所在的vue實例。  } } });
復制代碼


免責聲明!

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



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