首页 技术 正文
技术 2022年11月10日
0 收藏 705 点赞 5,026 浏览 5773 个字

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

说明:此组件基于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: '取消'
}
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,489
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,904
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,737
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,489
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,128
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,290