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