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 }

原文地址:https://www.cnblogs.com/wzq201607/p/vue_genForm.html

时间: 2024-11-05 14:51:37

vue动态表单的相关文章

动态表单数据库设计

需求: 能够根据数据库在界面动态显示表单,包括表单类型.名称等,并且必须提供 添加新表单,修改表单等功能. 为了满足客户不断的需求变化,有时候需要为某商品增加.修改.删除.属性,这样的话以往的数据库表就很难实现, 因为表的字段是定死了 如果你需要增加一个属性的时候 ,就必须修改表,听说这是不允许的~~. 所以我们要设计一个灵活的数据库 下面以电脑设备为例: pc 现有属性 name cpu ram disk 现在我们要为pc添加一个 mainboard 属性. 既然必须提供增加表单,那么我们创建

2017.2.28 activiti实战--第六章--任务表单(一)动态表单(待)

学习资料:<Activiti实战> 第六章 任务表单(一)动态表单 内容概览:本章要完成一个OA(协同办公系统)的请假流程的设计,从实用的角度,讲解如何将activiti与业务紧密相连. 第四章中讲解了两种表单:动态表单和外置表单的区别.这里将使用不同的表单来完成相同的功能. 1 动态表单:<activiti:formProperty> 2 外置表单:<activiti:formKey>

javaweb日记选(动态表单及表的实现)

Java语言也可以创建动态表单,如javaweb创建表单及表 应用场景 项目中往往需要动态的创建一个表单,或者添加一个新的数据模板,这时候因为需要在运行时动态的创建表以及动态的维护表字段甚至表关系 使得普通java解决方案变得困难重重. 实现工具 Hibernate + Spring + Groovy +Freemarker Hibernate 作用很简单负责创建数据库表这样可以避免我们自己去写复杂的sql和判断. Spring 作为桥梁起到连接纽带的作用 Groovy 做为动态语言,在项目运行

vue的表单提交

vue的表单提交需要基于vue-resource <template> <div class="hello"> <form @submit.prevent="submit"> <div> 姓名:<input type="text" v-model="user.name"> </div> <div> 性別: <label> <i

动态表单

毕业后,一直断断续续地在做这个,腻了! 从傻瓜式的字段定义: 到可视化设计: 页面效果还是一个样--丑: 可是这工具的用户,一直是我,ONLY ME! 动态表单

动态表单设计

公司前辈要我做一个动态表单数据库设计,思维愚钝,无法下手.后来前辈帮我把表结构画出来了,才茅塞顿开 现在和大家分享一下. 需求: 能够根据数据库在界面动态显示表单,包括表单类型.名称等,并且必须提供 添加新表单,修改表单等功能. 为了满足客户不断的需求变化,有时候需要为某商品增加.修改.删除.属性,这样的话以往的数据库表就很难实现, 因为表的字段是定死了 如果你需要增加一个属性的时候 ,就必须修改表,听说这是不允许的~~. 所以我们要设计一个灵活的数据库 下面以电脑设备为例: pc 现有属性 n

Struts动态表单的创建

一.在struts中如何实现动态表单的创建 (1)第一步:创建一个简单的注册页面: <body> <form action="/DynamicForm/register.do?flag=register" method="post"> u:<input type="text" name="name"/><br/> p:<input type="password&q

Angular动态表单生成(二)

ng-dynamic-forms源码分析 在两个开源项目中,ng-dynamic-forms的源码相较于form.io,比较简单,所以我还勉强能看懂,下面就我自己的理解进行简单分析,若有不对的地方,请大家多多指正. 整体结构分析 ng-dynamic-forms的主要代码均分布在packages文件夹下,其中的Core是各种控件的抽象,其他的文件夹是各个UI框架的具体封装,每个文件夹都是一个可独立编译运行的项目. Core文件夹内容分析 Core文件夹做的事情,基本上是对于各种组件.布局的抽象,

Angular动态表单生成(七)

动态表单生成之拖拽生成表单(上) 这个功能就比较吊炸天了,之前的六篇,都是ng-dynamic-forms自带的功能,可能很多的说明官方的文档都已经写了,我只是个搬运工,而在这篇文章中,我将化身一个工程师,来自己创造点东西,让我们一起来期待吧~ 导入相关类库 拖拽功能看似吊炸天,其实HTML5中已经有一套标准来定义它了,所以并没有那么难以实现,这篇关于拖拽的文章写得还可以,大家可以先看看:http://www.zhangxinxu.com/wordpress/2011/02/html5-drag