前言

  最近有一个需求是通过后台返回的数据,生成表单并添加校验。在做的过程中,动态表单挺好做,关键是校验。困扰了我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 },

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

最新文章

  1. OpenCASCADE Curve Length Calculation
  2. Apache设置页面认证(原创贴-转载请注明出处)
  3. DS Tree 已知先序、中序 =&gt; 建树 =&gt; 求后序
  4. 利用Lambda获取属性名称
  5. question about import google file
  6. JMeter学习-006-Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002 解决办法(windows 7)
  7. [SAP ABAP开发技术总结]文本文件、Excel文件上传下传
  8. codeforces 333B - Chips
  9. 如何实现XA式、非XA式Spring分布式事务
  10. @ContextConfiguration注解说明
  11. [USACO1.2.2]方块转换 Transformations
  12. nginx服务器的日志太多:定期执行脚本删除
  13. Android学习路线(二十七)键值对(SharedPreferences)存储
  14. 怎样从一个DLL中导出一个C++类
  15. Maven和Eclipse联合开发(转)
  16. 拜托!面试请不要再问我Spring Cloud底层原理
  17. 拦截$.ajax方法实现登录过期登录
  18. [z]表空间对应文件的AUTOEXTEND ON NEXT指定的值对性能的影响
  19. Linux的wget命令
  20. NLog日志框架简写用法

热门文章

  1. [Oracle19C 数据库管理] 管理PDB
  2. 解决 http://www.diamond-sh.com/favicon.ico 404 (Not Found) 报错问题
  3. ConstantBuffer
  4. Matchmaker Server 像素流送配对服务器
  5. SQLSERVER 存储过程里 执行sql字符串 并返回结果
  6. js中构造函数中this指向问题
  7. 利用Comparator对枚举类型进行排序的实现
  8. Expected indentation of 2 spaces but found 4
  9. Vue CLI创建Vue2项目
  10. 可视化 之D3 与echarts 对比以及应用场景