写点什么

Vue.js+ElementUI+vant 生成动态表单配置

用户头像
阿土
关注
发布于: 1 小时前

前言

我司最近在搭建一款后台管理系统,使用的是 Vue 全家桶配合 Element-ui,遇到一个问题,需要处理很多的表单,所以想到的解决方案是通过后台配置生成动态表单,这对于我来说也算是新的挑战,涉及的功能有动态表单渲染和验证,那么一起来学习一下我是如何实现的吧!


本文仅仅代表笔者自己的思路,如果您有更好的实现方式,可以在下方留下您宝贵的建议。笔者将十分感谢


开发准备

需要储备的知识点

  • 了解 Element ui 表单

  • 了解 Vue 中的 $set(target,key,value)方法

  • 了解 vant 中的表单组件


本项目是基于 vue-cli2.0 搭建的脚手架,在这里默认大家搭建好了,谁赞成,谁反对!


静态表单数据准备

后台返回的数据是这样的,这里我们拿一个 json 数据举例


{    "showName": "姓名",  // 名称    "showValue": null,    //值    "htmlElements": "输入框", // 表单类型    "fieldLength": 99,  // 字段长度    "requiredOrNot": 1,  //  是否必填}
复制代码


然后类型的话大概有以下几种


  • 输入框

  • 文本域

  • 日历控件

  • 下拉框

  • 单选框

  • 复选框


我们为每一种类型生成一种组件,Test.vue 组件里面


data(){    return{        fieldArray:[],// 表单字段集合        fieldObj:{},        sex:[{    // 性别            name:'男',            value:"male"        },{            name:"女",            value:"female"        }            ],        hobbies:[ // 爱好            {                name:"吃饭",                value:"吃饭"            },{                name:"玩游戏",                value:"玩游戏"            },{                name:"打豆豆",                value:"打豆豆"            },        ],        job:[{  // 职业            name:"医生",            value:"doctor"        },{            name:"老师",            value:"teacher"        },{            name:"司机",            value:"driver"        }            ]    }}
复制代码


这里准备多种日历控件是因为后续手机端使用 vant 组件的时候需要用到


由于 vue 中的数据是双向绑定的,所以只有在 data 里面的数据是可以实现双向绑定的,重新向 data 里面添加的数据无法达到双向绑定的效果,官网为我们提供了一个 set 方法。


作为靓仔的我,肯定很贴心的为大家准备了官网链接



官网链接


这里就不过多讲解,官网比较权威,本篇博客的重点是动态表单。

Vue.set(target,propertyName/index,value)

  • 参数

  • {Object | Array} target

  • {string | number} propertyName/index

  • {any} value

  • 返回值:设置的值。


用法


向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property (比如 this.myObject.newProperty = 'hi')


注意对象不能是 Vue 实例,或者 Vue 实例的根数据对象。

Element-ui 表单元素

官网链接

动态表单渲染

这里使用 axios 请求本地 json 数据,static/json/form.json


{  "data":[    {      "showName": "姓名",      "showValue": null,      "htmlElements": "输入框",      "fieldLength": 10,      "requiredOrNot": 1,      "desc":"请输入姓名"    },    {      "showName": "描述",      "showValue": null,      "htmlElements": "文本域",      "fieldLength": 99,      "requiredOrNot": 1,      "desc":"请输入描述"    },    {      "showName": "爱好",      "showValue": null,      "htmlElements": "复选框",      "requiredOrNot": 1,      "desc":"请选择爱好"    },    {      "showName": "性别",      "showValue": null,      "htmlElements": "单选框",      "requiredOrNot": 1    },    {      "showName": "出生日期",      "showValue": null,      "htmlElements": "日历控件",      "requiredOrNot": 1,      "desc":"请选择出生日期"    },    {      "showName": "结婚时间",      "showValue": null,      "htmlElements": "日历控件",      "requiredOrNot": 1,      "desc":"请选择结婚时间"    },    {      "showName": "职业",      "showValue": null,      "htmlElements": "下拉框",      "requiredOrNot": 1,      "desc":"请选择职业"    }  ]}
复制代码


Test.vue 文件


<template>    <div>        <h2>测试动态表单</h2>      <el-form :model="fieldObj" ref="ruleForm" label-width="180px" class="demo-ruleForm">        <template v-for="(item,index) of fieldArray">          <template v-if="item.htmlElements==='输入框'">            <el-form-item :label="item.showName">              <el-input v-model="fieldObj[item.showName]" :max="item.fieldLength" :placeholder="item.desc" show-word-limit></el-input>            </el-form-item>          </template>          <template v-if="item.htmlElements==='文本域'">            <el-form-item :label="item.showName">              <el-input type="textarea" rows="4" :placeholder="item.desc" v-model="fieldObj[item.showName]" :maxlength="item.fieldLength" show-word-limit></el-input>            </el-form-item>          </template>          <template v-if="item.htmlElements==='日历控件'">            <el-form-item :prop="item.showName" :label="item.showName">              <el-date-picker v-model="fieldObj[item.showName]" :name="item.showName" type="date"                              format="yyyy-MM-dd" value-format="yyyy-MM-dd"                              :placeholder="item.desc"              ></el-date-picker>            </el-form-item>          </template>          <template v-if="item.htmlElements==='下拉框'">            <el-form-item  :label="item.showName">              <el-select v-model="fieldObj[item.showName]" :placeholder="item.describe">                <el-option                  v-for="items in job"                  :key="items.name"                  :label="items.name"                  :value="items.value">                </el-option>              </el-select>            </el-form-item>          </template>          <template v-if="item.htmlElements==='单选框'">            <el-form-item  :label="item.showName">              <template v-for="(child,index) in sex">                <el-radio v-model="fieldObj[item.showName]" :label="child.value">{{child.name}}</el-radio>              </template>            </el-form-item>          </template>          <template v-if="item.htmlElements==='复选框'">            <el-form-item  :label="item.showName">              <el-checkbox-group v-model="fieldObj[item.showName]">                <template v-for="(child,index) of hobbies">                  <el-checkbox :label="child.name"></el-checkbox>                </template>              </el-checkbox-group>            </el-form-item>          </template>        </template>      </el-form>    </div></template>
<script> import axios from 'axios' export default { name: "Test", data(){ return{ fieldArray:[],// 表单字段集合 fieldObj:{}, sex:[{ // 性别 name:'男', value:"male" },{ name:"女", value:"female" } ], hobbies:[ // 爱好 { name:"吃饭", value:"吃饭" },{ name:"玩游戏", value:"玩游戏" },{ name:"打豆豆", value:"打豆豆" }, ], job:[{ // 职业 name:"医生", value:"doctor" },{ name:"老师", value:"teacher" },{ name:"司机", value:"driver" } ] } }, mounted(){ this.getFieldData(); }, methods:{ getFieldData(){ // 获取动态表单数据 axios.get("../static/json/form.json").then(data=>{ let response=data.data.data; this.fieldArray=response; for(let i=0;i<response.length;i++){ let item=response[i]; if(item.htmlElements==='复选框'){ this.$set(this.fieldObj,item.showName,[]); }else { this.$set(this.fieldObj,item.showName,item.showValue); } } }) } } }</script>
<style scoped>
</style>
复制代码



现在的话,表单已经全部渲染完毕了,也实现了双向绑定,现在需要做的是如何实现动态表单验证。


官网解释:Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可,


  • prop 字段

  • rules

  • model


在这里 rules 设置为动态的,而不是放在 data 里面提前写好,这里需要知道每一种类型的触发形式


  • 输入框/文本域 trigger: 'blur'

  • 单选框/复选框/日历控件/下拉框 trigger: 'change'

动态表单验证

对于表单中的每一种验证形式都了解之后,Test.vue 里面的文件就变成了


<template>    <div>        <h2>测试动态表单</h2>      <el-form :model="fieldObj" ref="ruleForm" label-width="180px" class="demo-ruleForm">        <template v-for="(item,index) of fieldArray">          <template v-if="item.htmlElements==='输入框'">            <el-form-item :label="item.showName" :prop="item.showName" :rules="item.requiredOrNot==1?[{ required: true, message: '请输入'+item.showName, trigger: 'blur' }]:[]">              <el-input v-model="fieldObj[item.showName]" :max="item.fieldLength"                        :placeholder="item.desc" show-word-limit ></el-input>            </el-form-item>          </template>          <template v-if="item.htmlElements==='文本域'">            <el-form-item :label="item.showName" :prop="item.showName" :rules="item.requiredOrNot==1?[{ required: true, message: '请输入'+item.showName, trigger: 'blur' }]:[]">              <el-input type="textarea" rows="4" :placeholder="item.desc" v-model="fieldObj[item.showName]" :maxlength="item.fieldLength" show-word-limit></el-input>            </el-form-item>          </template>          <template v-if="item.htmlElements==='日历控件'">            <el-form-item :prop="item.showName" :label="item.showName" :rules="item.requiredOrNot==1?[{ required: true, message: '请选择'+item.showName, trigger: 'change' }]:[]">              <el-date-picker v-model="fieldObj[item.showName]" :name="item.showName" type="date"                              format="yyyy-MM-dd" value-format="yyyy-MM-dd"                              :placeholder="item.desc"              ></el-date-picker>            </el-form-item>          </template>          <template v-if="item.htmlElements==='下拉框'">            <el-form-item  :label="item.showName" :prop="item.showName" :rules="item.requiredOrNot==1?[{ required: true, message: '请选择'+item.showName, trigger: 'change' }]:[]">              <el-select v-model="fieldObj[item.showName]" :placeholder="item.describe">                <el-option                  v-for="items in job"                  :key="items.name"                  :label="items.name"                  :value="items.value">                </el-option>              </el-select>            </el-form-item>          </template>          <template v-if="item.htmlElements==='单选框'">            <el-form-item  :label="item.showName" :prop="item.showName" :rules="item.requiredOrNot==1?[{ required: true, message: '请选择'+item.showName, trigger: 'change' }]:[]">              <template v-for="(child,index) in sex">                <el-radio v-model="fieldObj[item.showName]" :label="child.value">{{child.name}}</el-radio>              </template>            </el-form-item>          </template>          <template v-if="item.htmlElements==='复选框'">            <el-form-item  :label="item.showName" :prop="item.showName" :rules="item.requiredOrNot==1?[{ required: true, message: '请选择'+item.showName, trigger: 'change' }]:[]">              <el-checkbox-group v-model="fieldObj[item.showName]">                <template v-for="(child,index) of hobbies">                  <el-checkbox :label="child.name"></el-checkbox>                </template>              </el-checkbox-group>            </el-form-item>          </template>        </template>        <div class="text-align">          <el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>          <el-button @click="resetForm('ruleForm')">重置</el-button>        </div>      </el-form>    </div></template>
<script> import axios from 'axios' export default { name: "Test", data(){ return{ fieldArray:[],// 表单字段集合 fieldObj:{}, sex:[{ // 性别 name:'男', value:"male" },{ name:"女", value:"female" } ], hobbies:[ // 爱好 { name:"吃饭", value:"吃饭" },{ name:"玩游戏", value:"玩游戏" },{ name:"打豆豆", value:"打豆豆" }, ], job:[{ // 职业 name:"医生", value:"doctor" },{ name:"老师", value:"teacher" },{ name:"司机", value:"driver" } ] } }, mounted(){ this.getFieldData(); }, methods:{ getFieldData(){ // 获取动态表单数据 axios.get("../static/json/form.json").then(data=>{ let response=data.data.data; this.fieldArray=response; for(let i=0;i<response.length;i++){ let item=response[i]; if(item.htmlElements==='复选框'){ this.$set(this.fieldObj,item.showName,[]); }else { this.$set(this.fieldObj,item.showName,item.showValue); } } }) }, submitForm(formName){ // 提交验证 this.$refs[formName].validate((valid) => { if (valid) { console.log('提交数据'); } else { return false; } }); }, resetForm(formName) { // 重置表单 this.$refs[formName].resetFields(); } } }</script>
<style scoped>
</style>
复制代码


新增的内容有:


  • el-form-item 新增了:prop="item.showName"

  • el-form-item 新增了:rules="item.requiredOrNot==1?[{ required: true, message: '请选择'+item.showName, trigger: 'change' }]:[]"

  • el-form-item 新增了:rules="item.requiredOrNot==1?[{ required: true, message: '请输入'+item.showName, trigger: 'blur' }]:[]"

  • methods 里面新增了验证方法和重置表单的方法


vant 动态表单验证

由于 pc 端和手机端是配套使用的,所以手机端我们也实现动态表单的功能,


废话不多说上号!



还是拿 Test.vue 组件来举例子,对于移动端的话,首先需要安装 vant 依赖,默认大家已经安装好了。


vant官网

动态表单渲染

由于手机端没有下拉框这个组件,而是使用 Picker 选择器来代替,那么就需要思考一个问题,多个 picker 的话怎么实现一一对应呢?该怎么处理?



form.json 里面新增一个对象-城市,之前的代码还是可以复用


{    "showName": "城市",    "showValue": null,    "htmlElements": "下拉框",    "requiredOrNot": 1,    "desc":"请选择职业"}
复制代码


这样一来就有多个下拉框,从而来解决多个 picker 的问题。


Test.vue 的代码


html 代码区


<template>    <div>      <h2 class="title">测试vant动态表单</h2>      <van-form @submit="submitClaim">        <template v-for="(item,index) of fieldArray">          <template v-if="item.htmlElements==='输入框'">            <van-field :maxlength="item.fieldLength" show-word-limit v-model="fieldObj[item.showName]" :name="item.showName" :label="item.showName"/>          </template>          <template v-if="item.htmlElements==='文本域'">            <van-field rows="2"  autosize :label="item.showName" :name="item.showName" type="textarea"  v-model="fieldObj[item.showName]" :maxlength="item.fieldLength" show-word-limit/>          </template>          <template v-if="item.htmlElements==='日历控件'">            <van-field :name="item.showName" is-link :label="item.showName" :readonly="true" v-model="fieldObj[item.showName]" />          </template>          <template v-if="item.htmlElements==='复选框'">            <van-field :name="item.showName" :label="item.showName">              <template #input>                <van-checkbox-group v-model="fieldObj[item.showName]" direction="horizontal">                  <template v-for="(child,index) of hobbies">                    <van-checkbox :name="child.value">{{child.name}}</van-checkbox>                  </template>                </van-checkbox-group>              </template>            </van-field>          </template>          <template v-if="item.htmlElements==='单选框'">            <van-field :name="item.showName" :label="item.showName">              <template #input>                <van-radio-group v-model="fieldObj[item.showName]" direction="horizontal">                  <template v-for="(child,index) of sex">                    <van-radio :name="child.value">{{child.name}}</van-radio>                  </template>                </van-radio-group>              </template>            </van-field>          </template>          <template v-if="item.htmlElements==='下拉框'">            <van-field :name="item.showName" is-link :label="item.showName"  :readonly="true" v-model="fieldObj[item.showName]"/>          </template>        </template>      </van-form>    </div></template>
复制代码


JavaScript 代码区


  import axios from 'axios'    export default {        name: "Test",      data(){          return{            fieldArray:[],// 表单字段集合            fieldObj:{},            sex:[{    // 性别              name:'男',              value:"male"            },{              name:"女",              value:"female"            }            ],            hobbies:[ // 爱好              {                name:"吃饭",                value:"吃饭"              },{                name:"玩游戏",                value:"玩游戏"              },{                name:"打豆豆",                value:"打豆豆"              },            ],          }      },      mounted(){        this.getFieldArray();      },      methods:{        getFieldArray(){  // 获取本地动态表单配置json数据             axios.get("../../static/json/form.json").then(data=>{               let response=data.data.data;               this.fieldArray=response;               for(let i=0;i<response.length;i++){                 let item=response[i];                 if(item.htmlElements==='复选框'){                   this.$set(this.fieldObj,item.showName,[]);                 }else {                   this.$set(this.fieldObj,item.showName,item.showValue);                 }               }             })          },        submitClaim(taskInfo){
} } }
复制代码



现在的话基本实现了输入框,文本域,单选框,复选框的值双向绑定,下一步是解决多个日历框和下拉框的取值一一对应。


日历框和弹出层都是通过 v-model 来控制显示和隐藏,所以只需知道日历框和弹出层的个数,然后循环遍历处理就可以了,getFieldArray 方法重新处理


axios.get("../../static/json/form.json").then(data=>{    let response=data.data.data;    this.fieldArray=response;    for(let i=0;i<response.length;i++){        let item=response[i];        if(item.htmlElements==='复选框'){            this.$set(this.fieldObj,item.showName,[]);        }else if(item.htmlElements==='日历控件'){            this.$set(this.dateObj,item.showName,false); // 日历控件全部先隐藏            this.$set(this.fieldObj,item.showName,item.showValue);        }else if(item.htmlElements=='下拉框'){            this.$set(this.fieldObj,item.showName,item.showValue);            this.$set(this.dropDownObj,item.showName,false); // 弹出层全部先隐藏        }else {            this.$set(this.fieldObj,item.showName,item.showValue);        }    }})
复制代码


data 数据里面新增 dateObj 对象


dateObj:{},// 控制日期的显示隐藏
复制代码
处理日历控件

页面 html 新增相关内容


 <van-field :name="item.showName" is-link :label="item.showName" :readonly="true" v-model="fieldObj[item.showName]" @click="dateObj[item.showName]=true"/><template v-for="(item,key,index) of dateObj">   <van-calendar v-model="dateObj[key]" @confirm="(date)=>onConfirmTime(date,item,key)"/> </template>
复制代码


methods 新增方法


onConfirmTime(date,item,key){ // 日历控件    this.fieldObj[key]=this.formatDate(date);    this.dateObj[key]=false;},formatDate(date) {  // 格式化日期    let year=date.getFullYear();    let month=date.getMonth()+1;    let day=date.getDate();    if(month<10){        month='0'+month;    }    if(day<10){        day='0'+day;    }    return `${year}-${month}-${day}`;},
复制代码


使用 v-model 绑定提前写好的日期对象 dateObj,然后遍历对象来控制每一个日历控件的显示隐藏。


绑定对应的 key 值,这样就可以达到获取每一个日历对象点击之后对应的值。

处理下拉框

data 里面新增 dropDownObj 对象,dropDownTempObj 对象,dropDownMap map 对象


dropDownObj:{},// 控制下拉框的显示隐藏dropDownTempObj:{},// 下拉框对象,用于picker里面的值dropDownMap:new Map(),
复制代码


mounted 生命周期里面新增


this.dropDownMap.set("职业",["医生","老师","司机"]);this.dropDownMap.set("城市",["北京","上海","广州","深圳"])
复制代码


页面新增 html 内容


<van-field :name="item.showName" is-link :label="item.showName"  :readonly="true" v-model="fieldObj[item.showName]" @click="dropDownObj[item.showName]=true"/><template v-for="(item,key,index) of dropDownObj">    <van-popup v-model="dropDownObj[key]" position="bottom" :style="{width: '100%'}">        <van-picker show-toolbar  @confirm="(value)=>onConfirmDropdown(value,key)" @cancel="dropDownObj[key]=false" :columns="handleData(dropDownTempObj[key])"/>    </van-popup></template>
复制代码


methods 新增相关方法


onConfirmDropdown(value,key){  // 下拉框选中数据  this.dropDownObj[key]=false;  this.fieldObj[key]=value;},handleData(key){ // 下拉框获取每一个配置项  return this.dropDownMap.get(key);},
复制代码


getFieldArray 方法重写


axios.get("../../static/json/form.json").then(data=>{    let response=data.data.data;    this.fieldArray=response;    for(let i=0;i<response.length;i++){        let item=response[i];        if(item.htmlElements==='复选框'){            this.$set(this.fieldObj,item.showName,[]);        }else if(item.htmlElements==='日历控件'){            this.$set(this.dateObj,item.showName,false); // 日历控件全部先隐藏            this.$set(this.fieldObj,item.showName,item.showValue);        }else if(item.htmlElements=='下拉框'){            this.$set(this.fieldObj,item.showName,item.showValue);            this.$set(this.dropDownObj,item.showName,false); // 弹出层全部先隐藏            this.$set(this.dropDownTempObj,item.showName,item.showName);        }else {            this.$set(this.fieldObj,item.showName,item.showValue);        }    }})
复制代码


最终实现效果



可以看到最终所有的数据都实现了双向绑定,提交到后台的数据就是表单里面的数据,也可以全部获取到,最后需要实现的就是表单的验证的功能。

动态表单验证

对于输入框和文本域的验证比较简单,只需要添加 required 和 rules 验证规则就可以


输入框和文本域


<van-field :required="item.requiredOrNot==1?true:false":maxlength="item.fieldLength" show-word-limit v-model="fieldObj[item.showName]" :name="item.showName" :label="item.showName"  :rules="[{ required: true, message: '请填写'+item.showName }]"/>
复制代码


这样一来就基本实现了输入框和文本域的验证,至于其它的 form 表单类型的验证笔者还在研究当中

vant 动态表单处理全部代码

html 代码片段


<van-form @submit="submitClaim">    <template v-for="(item,index) of fieldArray">        <template v-if="item.htmlElements==='输入框'">            <van-field :maxlength="item.fieldLength" show-word-limit v-model="fieldObj[item.showName]" :name="item.showName" :label="item.showName"/>        </template>        <template v-if="item.htmlElements==='文本域'">            <van-field rows="2"  autosize :label="item.showName" :name="item.showName" type="textarea"  v-model="fieldObj[item.showName]" :maxlength="item.fieldLength" show-word-limit/>        </template>        <template v-if="item.htmlElements==='日历控件'">            <van-field :name="item.showName" is-link :label="item.showName" :readonly="true" v-model="fieldObj[item.showName]" @click="dateObj[item.showName]=true"/>        </template>        <template v-if="item.htmlElements==='复选框'">            <van-field :name="item.showName" :label="item.showName">                <template #input>                    <van-checkbox-group v-model="fieldObj[item.showName]" direction="horizontal">                        <template v-for="(child,index) of hobbies">                            <van-checkbox :name="child.value">{{child.name}}</van-checkbox>                        </template>                    </van-checkbox-group>                </template>            </van-field>        </template>        <template v-if="item.htmlElements==='单选框'">            <van-field :name="item.showName" :label="item.showName">                <template #input>                    <van-radio-group v-model="fieldObj[item.showName]" direction="horizontal">                        <template v-for="(child,index) of sex">                            <van-radio :name="child.value">{{child.name}}</van-radio>                        </template>                    </van-radio-group>                </template>            </van-field>        </template>        <template v-if="item.htmlElements==='下拉框'">            <van-field :name="item.showName" is-link :label="item.showName"  :readonly="true" v-model="fieldObj[item.showName]" @click="dropDownObj[item.showName]=true"/>        </template>    </template>    <van-button  type="info" round  native-type="submit" :style="{width:'100%',marginTop:'15px'}">提交</van-button></van-form><template v-for="(item,key,index) of dateObj">    <van-calendar v-model="dateObj[key]" @confirm="(date)=>onConfirmTime(date,item,key)"/></template><template v-for="(item,key,index) of dropDownObj">    <van-popup v-model="dropDownObj[key]" position="bottom" :style="{width: '100%'}">        <van-picker show-toolbar  @confirm="(value)=>onConfirmDropdown(value,key)" @cancel="dropDownObj[key]=false" :columns="handleData(dropDownTempObj[key])"/>    </van-popup></template>
复制代码


JavaScript 代码片段


import axios from 'axios'export default {    name: "Test",    data(){        return{            fieldArray:[],// 表单字段集合            fieldObj:{},            sex:[{    // 性别                name:'男',                value:"male"            },{                name:"女",                value:"female"            }                ],            hobbies:[ // 爱好                {                    name:"吃饭",                    value:"吃饭"                },{                    name:"玩游戏",                    value:"玩游戏"                },{                    name:"打豆豆",                    value:"打豆豆"                },            ],            dateObj:{ // 控制日期的显示隐藏
}, dropDownObj:{ // 控制下拉框的显示隐藏
}, dropDownTempObj:{ // 下拉框对象,用于picker里面的值
}, dropDownMap:new Map(), } }, mounted(){ this.getFieldArray(); this.dropDownMap.set("职业",["医生","老师","司机"]); this.dropDownMap.set("城市",["北京","上海","广州","深圳"]) }, methods:{ getFieldArray(){ // 获取本地动态表单配置json数据 axios.get("../../static/json/form.json").then(data=>{ let response=data.data.data; this.fieldArray=response; for(let i=0;i<response.length;i++){ let item=response[i]; if(item.htmlElements==='复选框'){ this.$set(this.fieldObj,item.showName,[]); }else if(item.htmlElements==='日历控件'){ this.$set(this.dateObj,item.showName,false); // 日历控件全部先隐藏 this.$set(this.fieldObj,item.showName,item.showValue); }else if(item.htmlElements=='下拉框'){ this.$set(this.fieldObj,item.showName,item.showValue); this.$set(this.dropDownObj,item.showName,false); // 弹出层全部先隐藏 this.$set(this.dropDownTempObj,item.showName,item.showName); }else { this.$set(this.fieldObj,item.showName,item.showValue); } } }) }, onConfirmTime(date,item,key){ // 日历控件 this.fieldObj[key]=this.formatDate(date); this.dateObj[key]=false; }, onConfirmDropdown(value,key){ // 下拉框选中数据 this.dropDownObj[key]=false; this.fieldObj[key]=value; }, handleData(key){ // 下拉框获取每一个配置项 return this.dropDownMap.get(key); }, formatDate(date) { // 格式化日期 let year=date.getFullYear(); let month=date.getMonth()+1; let day=date.getDate(); if(month<10){ month='0'+month; } if(day<10){ day='0'+day; } return `${year}-${month}-${day}`; }, submitClaim(taskInfo){ console.log(taskInfo); } }}
复制代码

总结

整体来说动态表单的处理综合难度不算很大,需要的是如何对数据进行处理,当然还有不足之处是没有做到对文件上传的处理,代码的优化程度没有做好,v-for 里面写了很多 v-if,是否可以使用单独的组件进行处理,这些都是有待需要考虑的问题。

结尾

如果觉得本篇博客对您有帮助的话,记得给作者三连,点赞👍👍👍,关注,收藏,您的支持就是我写作路上最大的动力,我们下篇文章见。

发布于: 1 小时前阅读数: 2
用户头像

阿土

关注

还未添加个人签名 2019.04.27 加入

还未添加个人简介

评论

发布
暂无评论
Vue.js+ElementUI+vant生成动态表单配置