Vue.js+ElementUI+vant 生成动态表单配置
前言
我司最近在搭建一款后台管理系统,使用的是 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 依赖,默认大家已经安装好了。
动态表单渲染
由于手机端没有下拉框这个组件,而是使用 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,是否可以使用单独的组件进行处理,这些都是有待需要考虑的问题。
结尾
如果觉得本篇博客对您有帮助的话,记得给作者三连,点赞👍👍👍,关注,收藏,您的支持就是我写作路上最大的动力,我们下篇文章见。
版权声明: 本文为 InfoQ 作者【阿土】的原创文章。
原文链接:【http://xie.infoq.cn/article/c1220f60d84d9deb75734ed8a】。文章转载请联系作者。
阿土
还未添加个人签名 2019.04.27 加入
还未添加个人简介
评论