vue动态表单
Posted wzq201607
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue动态表单相关的知识,希望对你有一定的参考价值。
项目需求,需要根据后台接口返回数据,动态添加表单内容
说明:此组件基于Ant Design of Vue
目前支持六种表单控件:文本输入框(TextInput)、文本域输入框(TextArea)、下拉选择框(SelectInput)、下拉多选(SelectMultiple)、日期(DataPicker)、日期精确到秒(DataPickerSen)
一、文本框
1 <template> 2 <a-form-item :label="label" v-bind="formItemLayout"> 3 <a-input 4 v-decorator="[`$fieldName`, initialValue: currentValue]" 5 :placeholder="placeHolder" 6 @input="onInputEvent" 7 /> 8 </a-form-item> 9 </template> 10 11 <script> 12 export default 13 name: ‘TextInput‘, 14 props: [‘name‘, ‘label‘, ‘value‘, ‘options‘, ‘fieldName‘, ‘placeHolder‘], 15 data() 16 return 17 currentValue: this.value, 18 formItemLayout: 19 labelCol: 20 xs: span: 24 , 21 sm: span: 8 22 , 23 wrapperCol: 24 xs: span: 24 , 25 sm: span: 12 26 27 28 29 , 30 methods: 31 onInputEvent(v) 32 this.$emit(‘input‘, this.name, v.target.value) 33 34 , 35 watch: 36 value(val) 37 this.currentValue = val 38 39 40 41 </script>
二、文本域
1 <template> 2 <a-form-item :label="label" v-bind="formItemLayout"> 3 <a-textarea 4 v-decorator="[`$fieldName`, initialValue: currentValue]" 5 :placeholder="placeHolder" 6 @input="onInputEvent" 7 /> 8 </a-form-item> 9 </template> 10 11 <script> 12 export default 13 name: ‘TextArea‘, 14 props: [‘name‘, ‘label‘, ‘value‘, ‘options‘, ‘fieldName‘, ‘placeHolder‘], 15 data() 16 return 17 currentValue: this.currentValue, 18 formItemLayout: 19 labelCol: 20 xs: span: 24 , 21 sm: span: 8 22 , 23 wrapperCol: 24 xs: span: 24 , 25 sm: span: 12 26 27 28 29 , 30 methods: 31 onInputEvent(v) 32 this.$emit(‘input‘, this.name, v.target.value) 33 34 , 35 watch: 36 currentValue(val) 37 this.currentValue = val 38 39 40 41 </script>
三、下拉框
1 <template> 2 <a-form-item :label="label" v-bind="formItemLayout"> 3 <a-select 4 v-decorator="[`$fieldName`, initialValue: currentValue]" 5 :placeholder="placeHolder" 6 @change="onInputEvent" 7 > 8 <a-select-option v-for="v in options" :key="v.dictId">v.dictName</a-select-option> 9 </a-select> 10 </a-form-item> 11 </template> 12 13 <script> 14 export default 15 name: ‘SelectInput‘, 16 props: [‘name‘, ‘label‘, ‘value‘, ‘options‘, ‘fieldName‘, ‘placeHolder‘], 17 data() 18 return 19 currentValue: this.value, 20 formItemLayout: 21 labelCol: 22 xs: span: 24 , 23 sm: span: 8 24 , 25 wrapperCol: 26 xs: span: 24 , 27 sm: span: 12 28 29 30 31 , 32 methods: 33 onInputEvent(value) 34 this.$emit(‘input‘, this.name, value) 35 36 , 37 watch: 38 value(val) 39 this.currentValue = val 40 41 42 43 </script>
四、日期
1 <template> 2 <a-form-item :label="label" v-bind="formItemLayout"> 3 <a-date-picker 4 :defaultValue="moment(currentValue, ‘YYYY-MM-DD‘)" 5 :placeholder="placeHolder" 6 @change="onInputEvent" 7 /> 8 </a-form-item> 9 </template> 10 11 <script> 12 import moment from ‘moment‘ 13 14 export default 15 name: ‘DataPicker‘, 16 props: [‘name‘, ‘label‘, ‘value‘, ‘options‘, ‘fieldName‘, ‘placeHolder‘], 17 data() 18 return 19 currentValue: this.value, 20 formItemLayout: 21 labelCol: 22 xs: span: 24 , 23 sm: span: 8 24 , 25 wrapperCol: 26 xs: span: 24 , 27 sm: span: 12 28 29 30 31 , 32 methods: 33 moment, 34 onInputEvent(value) 35 this.$emit(‘input‘, this.name, value.format(‘YYYY-MM-DD‘)) 36 37 , 38 watch: 39 value(val) 40 this.currentValue = val 41 42 43 44 </script>
五、表单生成逻辑
1 <template> 2 <div class="my-class"> 3 <a-form class="ant-advanced-search-form" :form="form"> 4 <a-row :gutter="24"> 5 <div v-for="(fieldConfig, index) in config.fieldsConfig" :key="index"> 6 <a-col :span="24"> 7 <a-divider>fieldConfig.fieldClassify</a-divider> 8 </a-col> 9 <a-col :span="12" v-for="(field, index) in fieldConfig.fields" :key="index"> 10 <component 11 :key="index" 12 :is="field.fieldType" 13 :label="field.label" 14 :fieldName="field.fieldName" 15 :placeHolder="field.placeHolder" 16 :value="value[field.name]" 17 @input="updateForm" 18 v-bind="field" 19 :options="field.options" 20 :ref="field.name" 21 ></component> 22 </a-col> 23 </div> 24 </a-row> 25 <a-row> 26 <a-col :span="24" :style=" textAlign: ‘center‘, marginTop: ‘20px‘ "> 27 <a-button :style=" marginRight: ‘8px‘ " @click="reset">onResetText</a-button> 28 <a-button type="primary" @click="submit">onSubmitText</a-button> 29 </a-col> 30 </a-row> 31 </a-form> 32 </div> 33 </template> 34 <script> 35 import TextInput from ‘./TextInput‘ 36 import TextArea from ‘./TextArea‘ 37 import SelectInput from ‘./SelectInput‘ 38 import SelectMultiple from ‘./SelectMultiple‘ 39 import DataPicker from ‘./PickerData‘ 40 import DataPickerSen from ‘./PickerDataSen‘ 41 42 export default 43 name: ‘FormGenerator‘, 44 components: TextArea, TextInput, SelectInput, SelectMultiple, DataPicker, DataPickerSen , 45 props: [‘config‘, ‘value‘], 46 data() 47 return 48 form: this.$form.createForm(this), 49 onSubmitText: this.config.buttons.onSubmitText || ‘提交‘, 50 onResetText: this.config.buttons.onResetText || ‘重置‘ 51 52 , 53 methods: 54 updateForm(fieldName, v) 55 this.value[fieldName] = v 56 , 57 submit() 58 this.form.validateFields((error, values) => 59 if (!error) 60 this.$emit(‘submit‘) 61 62 ) 63 , 64 reset() 65 this.form.resetFields() 66 67 68 69 </script> 70 71 <style lang="less" scoped> 72 .my-class 73 height: 600px; 74 overflow-y: scroll; 75 overflow-x: hidden; 76 77 78 .ant-advanced-search-form .ant-form-item 79 display: flex; 80 81 82 .ant-advanced-search-form .ant-form-item-control-wrapper 83 flex: 1; 84 85 86 #components-form-demo-advanced-search .ant-form 87 max-width: none; 88 89 </style>
六、调用
1 <template> 2 <div> 3 <form-generator :config="config" @submit="getFormData" :value="formData"></form-generator> 4 </div> 5 </template> 6 <script> 7 import axios from ‘@/utils/request‘ 8 import FormGenerator from ‘./form/FormGenerator‘ 9 10 export default 11 name: ‘‘, 12 props: , 13 components: FormGenerator , 14 data() 15 return 16 formData: , 17 config: 18 fieldsConfig: [], 19 buttons: 20 onSubmitText: ‘确定‘, 21 onResetText: ‘取消‘ 22 23 24 25 , 26 methods: 27 getFormData() 28 console.log(‘formData‘, this.formData) 29 , 30 queryAllFields() 31 axios.get(``).then(result => 32 if (result && result.code === 0) 33 this.config.fieldsConfig = result.fieldConfig 34 else 35 this.$message.error(result.msg) 36 37 ) 38 39 40 41 </script> 42 <style lang="less" scoped> 43 </style>
后台接口数据格式和页面样式可以参考,请根据自己的业务需求做相应调整,以下为我的项目后台接口数据格式
1 formData: 2 "river_name": ‘‘, 3 "sp_code": ‘‘, 4 "brief_name": ‘‘, 5 "simplegeometry": ‘‘ 6 , 7 config: 8 fieldsConfig: [ 9 "fields": [ 10 "fieldName": "river_name", 11 "name": "river_name", 12 "options": [], 13 "label": "河道(段)名称", 14 "fieldType": "TextInput", 15 "placeHolder": null 16 , 17 "fieldName": "sp_code", 18 "name": "sp_code", 19 "options": [], 20 "label": "水普编号", 21 "fieldType": "TextInput", 22 "placeHolder": null 23 ], "fieldClassify": ‘基本信息‘ 24 , 25 "fields": [ 26 "fieldName": "brief_name", 27 "name": "brief_name", 28 "options": [], 29 "label": "河道(段)简称", 30 "fieldType": "TextInput", 31 "placeHolder": null 32 , 33 "fieldName": "simplegeometry", 34 "name": "simplegeometry", 35 "options": [], 36 "label": "抽稀几何", 37 "fieldType": "TextInput", 38 "placeHolder": null 39 ], "fieldClassify": ‘附件信息‘ 40 , ], 41 buttons: 42 onSubmitText: ‘确定‘, 43 onResetText: ‘取消‘ 44 45
以上是关于vue动态表单的主要内容,如果未能解决你的问题,请参考以下文章