页面新增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>