项目需求,需要根据后台接口返回数据,动态添加表单内容

说明:此组件基于Ant Design of Vue

目前支持六种表单控件:文本输入框(TextInput)、文本域输入框(TextArea)、下拉选择框(SelectInput)、下拉多选(SelectMultiple)、日期(DataPicker)、日期精确到秒(DataPickerSen)

一、文本框

 <template>
<a-form-item :label="label" v-bind="formItemLayout">
<a-input
v-decorator="[`${fieldName}`, {initialValue: currentValue}]"
:placeholder="placeHolder"
@input="onInputEvent"
/>
</a-form-item>
</template> <script>
export default {
name: 'TextInput',
props: ['name', 'label', 'value', 'options', 'fieldName', 'placeHolder'],
data() {
return {
currentValue: this.value,
formItemLayout: {
labelCol: {
xs: { span: 24 },
sm: { span: 8 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 12 }
}
}
}
},
methods: {
onInputEvent(v) {
this.$emit('input', this.name, v.target.value)
}
},
watch: {
value(val) {
this.currentValue = val
}
}
}
</script>

二、文本域

 <template>
<a-form-item :label="label" v-bind="formItemLayout">
<a-textarea
v-decorator="[`${fieldName}`, {initialValue: currentValue}]"
:placeholder="placeHolder"
@input="onInputEvent"
/>
</a-form-item>
</template> <script>
export default {
name: 'TextArea',
props: ['name', 'label', 'value', 'options', 'fieldName', 'placeHolder'],
data() {
return {
currentValue: this.currentValue,
formItemLayout: {
labelCol: {
xs: { span: 24 },
sm: { span: 8 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 12 }
}
}
}
},
methods: {
onInputEvent(v) {
this.$emit('input', this.name, v.target.value)
}
},
watch: {
currentValue(val) {
this.currentValue = val
}
}
}
</script>

三、下拉框

 <template>
<a-form-item :label="label" v-bind="formItemLayout">
<a-select
v-decorator="[`${fieldName}`, {initialValue: currentValue}]"
:placeholder="placeHolder"
@change="onInputEvent"
>
<a-select-option v-for="v in options" :key="v.dictId">{{v.dictName}}</a-select-option>
</a-select>
</a-form-item>
</template> <script>
export default {
name: 'SelectInput',
props: ['name', 'label', 'value', 'options', 'fieldName', 'placeHolder'],
data() {
return {
currentValue: this.value,
formItemLayout: {
labelCol: {
xs: { span: 24 },
sm: { span: 8 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 12 }
}
}
}
},
methods: {
onInputEvent(value) {
this.$emit('input', this.name, value)
}
},
watch: {
value(val) {
this.currentValue = val
}
}
}
</script>

四、日期

 <template>
<a-form-item :label="label" v-bind="formItemLayout">
<a-date-picker
:defaultValue="moment(currentValue, 'YYYY-MM-DD')"
:placeholder="placeHolder"
@change="onInputEvent"
/>
</a-form-item>
</template> <script>
import moment from 'moment' export default {
name: 'DataPicker',
props: ['name', 'label', 'value', 'options', 'fieldName', 'placeHolder'],
data() {
return {
currentValue: this.value,
formItemLayout: {
labelCol: {
xs: { span: 24 },
sm: { span: 8 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 12 }
}
}
}
},
methods: {
moment,
onInputEvent(value) {
this.$emit('input', this.name, value.format('YYYY-MM-DD'))
}
},
watch: {
value(val) {
this.currentValue = val
}
}
}
</script>

五、表单生成逻辑

 <template>
<div class="my-class">
<a-form class="ant-advanced-search-form" :form="form">
<a-row :gutter="24">
<div v-for="(fieldConfig, index) in config.fieldsConfig" :key="index">
<a-col :span="24">
<a-divider>{{fieldConfig.fieldClassify}}</a-divider>
</a-col>
<a-col :span="12" v-for="(field, index) in fieldConfig.fields" :key="index">
<component
:key="index"
:is="field.fieldType"
:label="field.label"
:fieldName="field.fieldName"
:placeHolder="field.placeHolder"
:value="value[field.name]"
@input="updateForm"
v-bind="field"
:options="field.options"
:ref="field.name"
></component>
</a-col>
</div>
</a-row>
<a-row>
<a-col :span="24" :style="{ textAlign: 'center', marginTop: '20px' }">
<a-button :style="{ marginRight: '8px' }" @click="reset">{{onResetText}}</a-button>
<a-button type="primary" @click="submit">{{onSubmitText}}</a-button>
</a-col>
</a-row>
</a-form>
</div>
</template>
<script>
import TextInput from './TextInput'
import TextArea from './TextArea'
import SelectInput from './SelectInput'
import SelectMultiple from './SelectMultiple'
import DataPicker from './PickerData'
import DataPickerSen from './PickerDataSen' export default {
name: 'FormGenerator',
components: { TextArea, TextInput, SelectInput, SelectMultiple, DataPicker, DataPickerSen },
props: ['config', 'value'],
data() {
return {
form: this.$form.createForm(this),
onSubmitText: this.config.buttons.onSubmitText || '提交',
onResetText: this.config.buttons.onResetText || '重置'
}
},
methods: {
updateForm(fieldName, v) {
this.value[fieldName] = v
},
submit() {
this.form.validateFields((error, values) => {
if (!error) {
this.$emit('submit')
}
})
},
reset() {
this.form.resetFields()
}
}
}
</script> <style lang="less" scoped>
.my-class {
height: 600px;
overflow-y: scroll;
overflow-x: hidden;
} .ant-advanced-search-form .ant-form-item {
display: flex;
} .ant-advanced-search-form .ant-form-item-control-wrapper {
flex: 1;
} #components-form-demo-advanced-search .ant-form {
max-width: none;
}
</style>

六、调用

 <template>
<div>
<form-generator :config="config" @submit="getFormData" :value="formData"></form-generator>
</div>
</template>
<script>
import { axios } from '@/utils/request'
import FormGenerator from './form/FormGenerator' export default {
name: '',
props: {},
components: { FormGenerator },
data() {
return {
formData: {},
config: {
fieldsConfig: [],
buttons: {
onSubmitText: '确定',
onResetText: '取消'
}
}
}
},
methods: {
getFormData() {
console.log('formData', this.formData)
},
queryAllFields() {
axios.get(``).then(result => {
if (result && result.code === 0) {
this.config.fieldsConfig = result.fieldConfig
} else {
this.$message.error(result.msg)
}
})
}
}
}
</script>
<style lang="less" scoped>
</style>

后台接口数据格式和页面样式可以参考,请根据自己的业务需求做相应调整,以下为我的项目后台接口数据格式

 formData: {
"river_name": '',
"sp_code": '',
"brief_name": '',
"simplegeometry": ''
},
config: {
fieldsConfig: [{
"fields": [{
"fieldName": "river_name",
"name": "river_name",
"options": [],
"label": "河道(段)名称",
"fieldType": "TextInput",
"placeHolder": null
}, {
"fieldName": "sp_code",
"name": "sp_code",
"options": [],
"label": "水普编号",
"fieldType": "TextInput",
"placeHolder": null
}], "fieldClassify": '基本信息'
}, {
"fields": [{
"fieldName": "brief_name",
"name": "brief_name",
"options": [],
"label": "河道(段)简称",
"fieldType": "TextInput",
"placeHolder": null
}, {
"fieldName": "simplegeometry",
"name": "simplegeometry",
"options": [],
"label": "抽稀几何",
"fieldType": "TextInput",
"placeHolder": null
}], "fieldClassify": '附件信息'
}, ],
buttons: {
onSubmitText: '确定',
onResetText: '取消'
}
}

最新文章

  1. 可以ping通,但是不能connect
  2. DataItem,gridview,repeater数据控件数据绑定
  3. highcharts插件使用总结和开发中遇到的问题及解决办法
  4. PHP基础20:创建文件
  5. TYVJ P1088 treat Label:鞭笞人的DP
  6. CLM
  7. Android中获取网页表单中的数据
  8. cocos2d-x 3.3 显示中文
  9. dotnet webservice处理数据量过大,ajax请求返回500错误解决方案
  10. smartClient 1--框架介绍
  11. Aurelius vs mORMot vs EntityDAC Delphi 的 ORM框架
  12. django之admin管理工具
  13. 【转】fileno函数与ftruncate函数
  14. Lambda表达式学习(2)
  15. 读书笔记 effective c++ Item 28 不要返回指向对象内部数据(internals)的句柄(handles)
  16. 【POJ】4007.Flood-it!
  17. net-speeder
  18. asp.net mvc5 模式的现象思考
  19. DP Intro - Tree POJ2342 Anniversary party
  20. AC日记——pigs poj 1149

热门文章

  1. Spring Boot:使用Rabbit MQ消息队列
  2. memcached--add使用
  3. 最方便分布式爬虫管理框架--Gerapy
  4. C# 死锁 Task/AutoResetEvent
  5. Gym 101257G:24(尺取)
  6. POI自动调整列宽支持中文
  7. div+css 布局技巧总计
  8. 基于 MySQL Binlog 的 Elasticsearch 数据同步实践 原
  9. 完全平方数(C语言实现)
  10. 从后端到前端之Vue(一)写个表格试试水