上一部分總結了基礎常用的js表單校驗,包括原生以及框架,下面來總結這一個月涉及到的動態校驗:
動態表單校驗大致分為三種情況:
1. 首先是固定校驗規則,但是表單元件是動態生成的,例如:在表單或者表格裡有“增加”功能,增加一行,給新生成的表單元件新增校驗規則。
2. 第二類就是元件固定,但是校驗規則會隨著其他條件的變化而變化,例如:基本的最常見的例子是確認密碼的校驗,判斷第二次輸入的密碼與第一次輸入是否一致。
3. 最後,比較複雜的就是以上兩類情況的混合情況,動態生成的表單,且校驗規則也是動態變化的。
接下來還是用最直觀的舉例子來解釋用法:
這裡使用了element自帶的rules,其他框架同理,也可以自己繫結方法,原生的用blur,focus等也可以
一:固定校驗規則+元件動態生成
要實現的效果:點選第一行的新增生成下面的表格,表格各自校驗
實現方法程式碼舉例:
html :(放到表格裡的元件,和表單同理)
1 <el-table-column align="center" label="金額標準" prop="level">
2 <template slot-scope="scope">
3 <span v-if="scope.row.edit">{{ scope.row.level}}</span>
4 <el-form-item v-show="!scope.row.edit" :prop="'list.'+scope.$index+'.level'" :rules="rules.level">
5 <el-input v-model="scope.row.level" autofocus placeholder="請輸入金額標準"></el-input>
6 </el-form-item>
7 </template>
8 </el-table-column>
js :(校驗規則以及觸發方式定義)
1 data() {
2 return {
3 rules:{
4 level: [
5 {required: true, message: '請輸入金額標準', trigger: ['blur', 'change']},
6 { validator:function(rule,value,callback){
7 if(/^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(Number(value)) == false||Number(value)>10000){
8 callback(new Error("請輸入數字,可保留兩位小數,最大不超過10000"));
9 }else if(/^(([1-9][0-9]*)|(([0]\.\d{1,2}|[1-9][0-9]*\.\d{1,2})))$/.test(Number(value)) == false){
10 callback(new Error("請輸入數字,可保留兩位小數,最大不超過10000"));
11 }else{
12 callback();
13 }
14 }, trigger:['blur', 'change']
15 }
16 ],
17 }
18 }
19 }
js:(實現方式)
1 formValidate(formName){
2 this.$refs[formName].validate((valid) => {
3 if(valid) {
4 this.validateForm=true;
5 }else{
6 this.$message.warning("請確認輸入資訊無誤!");
7 this.validateForm=false;
8 }
9 });
10 return this.validateForm;
11 }
呼叫formValidate方法即可。
二:固定元件+動態校驗規則
要實現的效果:(element官方舉例)
實現方法程式碼舉例:
html:
1 <el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm">
2 <el-form-item label="密碼" prop="pass">
3 <el-input type="password" v-model="ruleForm.pass" autocomplete="off"></el-input>
4 </el-form-item>
5 <el-form-item label="確認密碼" prop="checkPass">
6 <el-input type="password" v-model="ruleForm.checkPass" autocomplete="off"></el-input>
7 </el-form-item>
8 </el-form>
js:(校驗規則可以定義到return之前,也可以直接放到rules裡)
1 data() {
2 var validatePass = (rule, value, callback) => {
3 if (value === '') {
4 callback(new Error('請輸入密碼'));
5 } else {
6 if (this.ruleForm.checkPass !== '') {
7 this.$refs.ruleForm.validateField('checkPass');
8 }
9 callback();
10 }
11 };
12 var validatePass2 = (rule, value, callback) => {
13 if (value === '') {
14 callback(new Error('請再次輸入密碼'));
15 } else if (value !== this.ruleForm.pass) {
16 callback(new Error('兩次輸入密碼不一致!'));
17 } else {
18 callback();
19 }
20 };
21 return {
22 ruleForm: {
23 pass: '',
24 checkPass: ''
25 },
26 rules: {
27 pass: [
28 { validator: validatePass, trigger: 'blur' }
29 ],
30 checkPass: [
31 { validator: validatePass2, trigger: 'blur' }
32 ]
33 }
34 };
三:動態生成元件+動態校驗規則
要實現的效果:三個元件分別縱向對比校驗,各元件個數不固定,為動態生成,各自校驗規則也相互影響,人數2依附於人數1的輸入值。
實現方法程式碼舉例:
html:(繫結prop以及rules)
1 <tr>
2 <td>
3 <div>
4 <div><label class="col-sm-4 control-label addbefore">天數</label>
5 </div>
6 </div>
7 </td>
8 <td>
9 <div>
10 <template v-for="(item, index) in form.list1">
11 <el-form-item
12 :key="item.key"
13 :id="item.key"
14 :name="item.key"
15 style="float: left;"
16 :prop="'list1.' + index +'.a_value'"
17 :rules="rules.a_value1">
18 <el-input v-model.number="item.a_value"></el-input>
19 <span>天</span>
20 </el-form-item>
21 </template>
22 </div>
23 </td>
24 </tr>
25 <tr>
26 <td>
27 <div>
28 <label>人數1</label>
29 </div>
30 </td>
31 <td>
32 <div>
33 <template v-for="(domain, index) in form.list2">
34 <el-form-item
35 :key="domain.key"
36 :id="domain.key"
37 :name="domain.value"
38 style="float: left;"
39 :prop="'list2.' + index +'.b_value'"
40 :rules="rules.b_value">
41 <el-input v-model.number="domain.b_value"></el-input>
42 <span>人</span>
43 </el-form-item>
44 </template>
45 </div>
46 </td>
47 </tr>
48 <tr>
49 <td>
50 <div>
51 <label>人數2</label>
55 </div>
56 </td>
57 <td>
58 <div>
59 <template v-for="(domain, index) in form.list3">
60 <el-form-item
61 :key="domain.key"
62 :id="domain.key"
63 :name="domain.value"
64 style="float: left;"
65 :prop="'list3.' + index +'.c_value'"
66 :rules="rules.c_value">
67 <el-input v-model.number="domain.c_value"></el-input>
68 <span>人</span>
69 </el-form-item>
70 </template>
71 </div>
72 </td>
73 </tr>
js :(資料及校驗規則定義)
1 data(){
2 var me=this
3 return {
4 form:{
5 list1:[],
6 list2:[],
7 list3:[]
8 }
9 rlues:{
10 a_value: [
11 { required: true, message: '請輸入', trigger: ['blur', 'change'] },
12 { type: 'number', message: '請輸入數字', trigger: ['blur', 'change']},
13 {
14 validator: (rule, value, callback) => {
15 if (value > 200) {
16 callback(new Error('天數應小於200'))
17 } else {
18 callback()
19 }
20 },
21 trigger: ['blur', 'change']
22 }
23 ],
24 b_value:[
25 { required: true, message: '請輸入', trigger: ['blur', 'change'] },
26 { type: 'number', message: '請輸入數字', trigger: ['blur', 'change']},
27 {
28 validator: (rule, value, callback) => {
29 if (value > 100) {
30 callback(new Error('人數1應小於100'))
31 } else {
32 callback()
33 }
34 },
35 trigger: ['blur', 'change']
36 }
37 ],
38 c_value:[
39 { required: true, message: '請輸入', trigger: ['blur', 'change'] },
40 { type: 'number', message: '請輸入數字', trigger: ['blur', 'change']},
41 {
42 validator: (rule, value, callback) => {
43 let index=Number(rule.field.substr(6, 1))
44 let sc=(me.form.list2[index].b_value)*0.1
45 if (value > sc) {
46 callback(new Error('人數2不超過人數1的10%'))
47 } else {
48 callback()
49 }
50 },
51 trigger: ['blur', 'change']
52 }
53 ]
54 }
55 }
56 }
js:(實現方式)
1 formValidate(formName){
2 this.$refs[formName].validate((valid) => {
3 if(valid) {
4 this.validateForm=true;
5 }else{
6 this.$message.warning("請確認輸入資訊無誤!");
7 this.validateForm=false;
8 }
9 });
10 return this.validateForm;
11 }
總結:
這三種情況其實基本原理是相同的,即是在變化的元素以及變化的標準怎麼比較,首先來說確定兩點,一是要繫結prop,動態雙向繫結,相當於生成元件是時給該元素生成一個標識,一般來說動態繫結寫法如下:
:prop="'list.' + index +'.value'"
或者寫成
:prop="'list.'+scope.$index+'.value'"
其次,是繫結一個規則:
:rules="rules.value"
然後就是具體校驗,可以寫到html裡,也可以寫到js裡,一般來說有校驗方法的寫到js裡,需要注意的是 validator: (rule, value, callback) => { },這個回撥方法裡的三個引數:
第一個引數 rule,為繫結元素的prop,主要用來取到需要進行比較的值,即規則;
第二個引數 value,為此時輸入的內容,和規則作比較,是否符合;
第三個引數 callback,為校驗完的回撥函式,校驗成功或失敗的提示在callback函式中執行;
以上為動態校驗總結。
這兩篇內容詳細記錄了我遇到的,以及所有能想到的前端校驗的情況的相關內容,歡迎補充。