摘要:本文将介绍如何使用vue和elment ui组件库实现一个简单的动态表单生成的Demo。主要涉及两个.vue文件的书写,一个是动态表单生成的组件文件,一个是使用该动态表单生成的组件。
1.动态表单生成组件
这里仅集成了输入框、选择框、日期框三种类型的表单项;
其他类型的表单元素,比如单选框、复选框等,也可以根据需要进行类似的处理。
可以动态计算每一行放置的表单数。
<template>
<div>
<el-form :model="data" :rules="rules" :label-width="labelWidth" :disabled="formDisabled">
<el-row :gutter="10" style="display: flex; flex-wrap: wrap">
<template v-for="(field, index) in formFields">
<el-col :key="index" :span="calculateSpanSize(field)">
<el-form-item
:prop="field.name"
:label="field.label"
:rules="field.rules"
:require="field.require ? field.required() : false"
v-bind="field.bind"
>
<el-input
v-if="field.type === 'text'"
:type="field.type"
:id="field.name"
:name="field.name"
v-model="data[field.name]"
:style="{ width: field.width || '100%' }"
/>
<el-select
v-else-if="field.type === 'select'"
:id="field.name"
v-model="data[field.name]"
:style="{ width: field.width || '100%' }"
>
<el-option
v-for="(option, optionIndex) in field.options"
:key="optionIndex"
:value="option.value"
:label="option.label"
:style="{ width: field.width || '100%' }"
>
{{ option.label }}
</el-option>
</el-select>
<el-date-picker
v-else-if="field.type === 'date'"
v-model="data[field.name]"
:type="field.type"
placeholder="选择日期"
:style="{ width: field.width || '100%' }"
>
</el-date-picker>
</el-form-item>
</el-col>
<!-- 其他类型的表单元素,比如单选框、复选框等,也可以根据需要进行类似的处理 -->
</template>
</el-row>
<el-row><el-button type="success" @click="submitForm">提交</el-button></el-row>
</el-form>
</div>
</template>
<script>
export default {
name: 'MyFrom',
props: {
labelWidth: {
type: String,
default: '100px'
},
rules: {
type: Object,
default: () => {}
},
formFields: {
type: Array,
default: () => []
},
data: {
type: Object,
default: () => {}
},
spanSize: {
type: Number,
default: 2,
validator: value => {
return value <= 5
}
},
disabled: {
type: Boolean,
default: false
}
},
data() {
return {}
},
created() {},
computed: {
formDisabled() {
return typeof disabled === 'function' ? this.disabled() : this.disabled
}
},
methods: {
submitForm() {
// 处理表单提交逻辑
console.log('Form Data:', this.data)
this.$parent.submintData(this.data)
},
calculateSpanSize(item) {
const span = item.span || 1
const spanTemp = (24 / this.spanSize) * span
return spanTemp > 24 ? 24 : spanTemp
}
}
}
</script>
2.使用动态表单的父组件
1.引入动态表单生成组件
2.对表单的属性进行配置
3.点击按钮调用父组件的提交数据函数,打印表单提交数据,看数据是否绑定成功
<template>
<div style="width: 800px">
<my-form :form-fields="formFields" :data="formData" :span-size="2"></my-form>
</div>
</template>
<script>
import MyForm from './MyForm.vue'
const defaultFormData = {
name: '',
gender: '',
birthday: '',
enabled: true,
address: '',
id: ''
}
export default {
name: 'HelloWorld',
components: { MyForm },
props: {
msg: String
},
data() {
return {
isEdit: false,
visible: false,
formFields: [
{
type: 'text',
label: '姓名',
name: 'name',
rules: [{ required: true, trigger: 'blur', message: '请输入姓名' }],
},
{
type: 'select',
label: '性别',
name: 'gender',
options: [
{ label: '男', value: '1' },
{ label: '女', value: '0' }
]
},
{ type: 'date', label: '生日', name: 'birthday' },
{
type: 'text',
label: '家庭地址',
name: 'address',
rules: [{ required: true, trigger: 'blur', message: '请输入家庭地址' }],
}
// 可根据需要添加更多的表单字段
],
formData: Object.assign({}, defaultFormData)
}
},
methods: {
submintData() {
console.log('11111' + JSON.stringify(this.formData))
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
提交结果:
3.思考
1.在设计动态表单生成组件时,可以使用component标签改进,而不是为每一种类型的表单项都写一个if判断,毕竟表单项类型比较多;后期会对这个点进行改进;
2.提交按钮可以放到父组件,动态表单生成组件就只负责生成表单以及绑定数据等逻辑的操作。
3.当你在一个 el-row
中包含多个 el-col
(列)时,你可以使用 gutter
属性来设置列之间的空隙,以增加页面的可读性和美观度。