element ui動態生成表單數據與校驗(后台傳入數據)


  前言

  最近有一個需求是通過后台返回的數據,生成表單並添加校驗。在做的過程中,動態表單挺好做,關鍵是校驗。困擾了我2天,最后通過查找資料和“運氣”終於解決了。解決問題關鍵點:vue的響應式。官方鏈接:https://cn.vuejs.org/v2/guide/reactivity.html

  官方是這樣說的:受現代 JavaScript 的限制 (而且 Object.observe 也已經被廢棄),Vue 無法檢測到對象屬性的添加或刪除。由於 Vue 會在初始化實例時對屬性執行 getter/setter 轉化,所以屬性必須在 data 對象上存在才能讓 Vue 將它轉換為響應式的。例如:

var vm = new Vue({
  data:{
    a:1
  }
})

// `vm.a` 是響應式的

vm.b = 2
// `vm.b` 是非響應式的

 

        對於已經創建的實例,Vue 不允許動態添加根級別的響應式屬性。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套對象添加響應式屬性。例如,對於:

Vue.set(vm.someObject, 'b', 2)

  您還可以使用 vm.$set 實例方法,這也是全局 Vue.set 方法的別名:

this.$set(this.someObject,'b',2)

  有時你可能需要為已有對象賦值多個新屬性,比如使用 Object.assign() 或 _.extend()。但是,這樣添加到對象上的新屬性不會觸發更新。在這種情況下,你應該用原對象與要混合進去的對象的屬性一起創建一個新的對象

// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })`
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })

  回到正題

  原型一:單層循環生成的表單(簡單,沒有遇到問題

  1.表單

 1 <el-form label-width="140px" :model="goodForm" size="small" style="width: 750px;">
 2   <el-col :key="index" :span="12" v-if="!(index%2==0)" v-for="(item,index) in goodForm.specSPUParams">
 3     <el-form-item :label="item.k" :prop="'specSPUParams.'+index+'.v'" :rules="[{required: true, message: item.k+'不能為空', trigger: 'blur'}]">
 4        <el-input v-model="item.v"></el-input>
 5     </el-form-item>
 6   </el-col>
 7   <el-col :key="index" :span="12" v-if="index%2==0" v-for="(item,index) in goodForm.specSPUParams">
 8     <el-form-item :label="item.k">
 9        <el-input v-model="item.v"></el-input>
10     </el-form-item>
11   </el-col>
12 </el-form>

  2.數據初始化聲明

1 data() {
2    return { 
3      goodForm: {
4        specSPUParams: []
5      }
6    }
7 }

  3.后台返回的數據結構

   

  原型二:多層循環生成表單

     需求是:根據后台返回的數據生成一個表單,如圖一;各表單輸入一個,動態添加一個輸入框,如圖二;這里只進行了各表單的第一個輸入框進行校驗。

     遇到的問題:輸入框輸入了值,校驗不能消失。

     解決方法:vue響應式的理解

 

 

  

 

 

   

 

 

  1.表單

 1 <el-form label-width="110px" :model="goodForm.specSKUParams" ref="sssss" size="small" style="width: 700px;" class="demo-dynamic">
 2    <div :key="index" v-for="(array,key,index) in goodForm.specSKUParams">
 3       <el-form-item v-for="(item, indexA) in array" :label="key" v-if="indexA===0" :key="indexA" :prop="key+'.'+indexA+'.v'"
 4               :rules="[{required: true, message: key+'不能為空', trigger: 'blur'}]">
 5          <el-input placeholder="請輸入參數值" v-model="item.v" style="width: 500px;" @change="skuChange(key,indexA)"></el-input>
 6          <el-button class="btnG" v-if="indexA+1!==array.length" @click.prevent="removeDomain(item,key)" icon="el-icon-delete-solid" type="text" 
            style
="font-size: 18px;color: #545C64;"></el-button> 7 </el-form-item> 8 <el-form-item v-for="(item, indexA) in array" v-if="!(indexA===0)" :key="indexA"> 9 <el-input placeholder="請輸入參數值" v-model="item.v" style="width: 500px;" @change="skuChange(key,indexA)"></el-input> 10 <el-button class="btnG" v-if="indexA+1!==array.length" @click.prevent="removeDomain(item,key)" icon="el-icon-delete-solid" type="text" 11 style="font-size: 18px;color: #545C64;"></el-button> 12 </el-form-item> 13 </div> 14 </el-form>

  2.數據初始化聲明

1 data() {
2   return {
3     goodForm: {
4       specSKUParams: {}
5     }
6  }
7 }

  3.獲得后台數據 (第2行的commonGet是自己封裝的ajax請求第4行是解決問題的關鍵點:給specSKUParams添加一個屬性,這樣此屬性就具有響應式)

 1 getSpecParams() {
 2    commonGet('item/spec/querySpecParam?cID=76').then(res => {
 3      res.data.data.rows.forEach(item => {
 4         this.$set(this.goodForm.specSKUParams,item.name,true);
 5         this.goodForm.specSKUParams[item.name]=[{
 6            v:''
 7         }]
 8      })
 9    })
10  },

  4.附帶兩個方法(動態增加輸入框;動態刪除輸入框)

 1 skuChange(key, index) {
 2   //console.log(key);
 3   let len = this.goodForm.specSKUParams[key].length;
 4   //console.log(len)
 5   if (index + 1 === len) { //如果操作的是最后一個輸入框就再添加一個輸入框
 6     this.goodForm.specSKUParams[key].push({
 7       v: ''
 8     });
 9   }
10 },
11 removeDomain(item,key){
12   //console.log(item);
13   //console.log(key);
14   let index=this.goodForm.specSKUParams[key].indexOf(item);
15   this.goodForm.specSKUParams[key].splice(index,1);
16 },

  總結:學習一時爽,一直學習一直爽!

 

      

 

 


免責聲明!

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



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