• 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=" 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=" 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=" 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=" 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 },

      总结:学习一时爽,一直学习一直爽!

          

  • 相关阅读:
    统一前后台数据交互格式
    volatile关键字 学习记录2
    利用AOP与ToStringBuilder简化日志记录
    JAVA的那些数据结构实现总结,实现,扩容说明
    JAVA中的数据结构
    对把JDK源码的一些注解,笔记
    分析下为什么spring 整合mybatis后为啥用不上session缓存
    JAVA内存关注总结,作为个程序员需要对自己系统的每块内存做到了如指掌
    写颗搜索二叉树动动脑,开启今年的旅程,新年快乐
    内存快照排查OOM,加密时错误方法指定provider方式错误引起的OOM
  • 原文地址:https://www.cnblogs.com/supwang-learn-enjoy-success/p/11970597.html
Copyright © 2020-2023  润新知