js-動態表單校驗-吐血總結最近遇到的變態表單校驗2---element+原生

花開不敗zy發表於2021-06-25

上一部分總結了基礎常用的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      }],
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></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><span></span>
20        </el-form-item>
21      </template>
22    </div>
23  </td>
24 </tr>
25<tr>
26  <td>
27    <div><label>人數1</label></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><span></span>
43        </el-form-item>
44      </template>
45    </div>
46  </td>
47</tr>
48<tr>
49  <td>
50    <div><label>人數2</label></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><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函式中執行;

 

以上為動態校驗總結。

這兩篇內容詳細記錄了我遇到的,以及所有能想到的前端校驗的情況的相關內容,歡迎補充。

    

 

相關文章