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动态表单的主要内容,如果未能解决你的问题,请参考以下文章

请教个vue动态生成form表单,表单里有单选项radio?

vue通过后端返回值动态生成表单及动态表单的数据提交

vue通过后端返回值动态生成表单及动态表单的数据提交

Angular 动态增减表单项

vue动态表单

Vue中动态增加表单项的方法