前言
我司最近在搭建一款后台管理系統,使用的是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,是否可以使用單獨的組件進行處理,這些都是有待需要考慮的問題。
結尾
如果覺得本篇博客對您有幫助的話,記得給作者三連,點贊👍👍👍,關注,收藏,您的支持就是我寫作路上最大的動力,我們下篇文章見。