Element UI el-form 表单封装思路
思路一: 封装一个组件。
将不同类型的组件都封装进一个组件,然后利用 v-if 根据传入的 type 来进行判断展示某一个表单的展示和隐藏
代码如下:
<Form
ref="ruleForm"
:model="ruleForm"
:rules="rules"
:label-width="labelWidth"
size="mini"
:inline="inline"
class="ruleForm"
>
<div
class="card-con"
v-for="(item, itemIndex) in layoutInfo"
:key="itemIndex"
>
<div
class="form-item"
v-for="(items, itemsIndex) in item.info"
:key="itemsIndex"
>
<!-- 单选框 -->
<span>
<FormItem>
<RadioGroup v-model="ruleForm[radiosItem.resource]">
<Radio>{{ radioItem.text }}</Radio
>
</RadioGroup>
</FormItem>
</span>
<!-- input框 -->
<span>
<FormItem>
<el-autocomplete
class="inline-input"
v-if="inputItem.dropdown && inputItem.type === 'autocomplete'"
></el-autocomplete>
<Input
class="item-input"
v-else-if="inputItem.dropdown"
/>
<Select v-else>
<Option></Option>
</Select>
</FormItem>
</span>
<!-- 点击input框出现弹框的-->
<span>
<FormItem>
<Input/>
</FormItem>
</span>
<!-- 日期选择框 -->
<span v-if="items.dateBoole">
<FormItem :label="items.timeMessage">
<DatePicker >
></DatePicker>
</FormItem>
</span>
</div>
</div>
</Form>
思路二:将每一种 form 表单类型 都单独封装为一个 组件
创建一个文件夹,将每一种 form 表单类型都单独封装为一个组件,最后新建一个 js 文件,将前面封装的所有 form 表单组件都通过
defineAsyncComponent()
异步 引入。
使用: 使用时,通过 vue 提供的component is
组件来进行使用。
效果如下
部分注意事项.
- v-model 数据双绑时,可以单独 声明一个对象,然后根据配置的 prop 进行双绑.
部分代码呈现
单文件封装
接受两个参数即可
- 双绑数据。
- 设置组件的相关属性对象。
<template>
<div class="fSelect">
<el-select
v-model="obj[meta.fProp]"
:filterable="meta.isFilterable"
:disabled="meta.isDisabled"
placeholder="请选择"
clearable
>
<el-option
v-for="item in meta.options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
<slot></slot>
</div>
</template>
<script>
export default {
name: 'fSelect',
props: {
meta: {
type: Object,
default() {
return {
fProp: ''
}
}
},
obj: Object
}
}
</script>
<style></style>
汇总表单的 js 文件:
import { defineAsyncComponent } from "vue";
const formMap = {
FInput: defineAsyncComponent(() =>
import("@/components/form/items/fInput.vue")
),
FRadio: defineAsyncComponent(() =>
import("@/components/form/items/fRadio.vue")
),
FSwitch: defineAsyncComponent(() =>
import("@/components/form/items/fSwitch.vue")
),
FSelect: defineAsyncComponent(() =>
import("@/components/form/items/fSelect.vue")
),
FCheckbox: defineAsyncComponent(() =>
import("@/components/form/items/fCheckbox.vue")
),
FDateTimePicker: defineAsyncComponent(() =>
import("@/components/form/items/fDateTimePicker.vue")
),
FSelectUser: defineAsyncComponent(() =>
import("@/components/form/items/fSelectUser.vue")
),
FPartNo: defineAsyncComponent(() =>
import("@/components/form/items/fPartNo.vue")
),
FSelectSupplier: defineAsyncComponent(() =>
import("@/components/form/items/fSelectSupplier.vue")
),
FSupplierMaster: defineAsyncComponent(() =>
import("@/components/form/items/fSupplierMaster.vue")
),
FCascader: defineAsyncComponent(() =>
import("@/components/form/items/fCascader.vue")
),
};
export default formMap;
组件封装 component 使用部分代码:
<template>
<div class="formModel">
<el-row>
<el-form
ref="refForm"
:model="formList.form"
:rules="formList.formRules"
:label-width="labelWidth"
class="demo-form-inline"
>
<template v-for="(item, index) in formList.fileds">
<el-col :span="item.span" :key="index">
<el-form-item :prop="item.formProp" :label="item.meta.fLabel">
<component
:is="formMap[item.formType]"
:meta="item.meta"
:obj="formList.form"
></component>
</el-form-item>
</el-col>
</template>
</el-form>
</el-row>
</div>
</template>
<script>
import formMap from './formMap'
export default {
name: 'formModel',
props: {
// 表单所需相关属性
formList: {
type: Object,
default() {
return {
fileds: [],
form: {}
}
}
},
labelWidth: {
type: String,
default: 'auto'
}
},
data() {
return {
formMap
}
},
methods: {
modelRef() {
return this.$refs.refForm
}
}
}
</script>
配置项相关代码:
<FormContainerModel
ref="partOneModelRef"
:formList="partOneFormList"
></FormContainerModel>
partOneFormList: {
formRules: {
issueDescribe: [
{ required: true, message: '请输入', trigger: ['blur'] }
]
},
fileds: [
{
formType: 'FInput',
span: 24,
meta: { fLabel: '案例编号', fProp: 'expandNo' }
},
{
formType: 'FSelect',
span: 12,
meta: { fLabel: '问题来源', fProp: 'supplierName', options: [] }
},
{
formType: 'FSelect',
span: 12,
meta: { fLabel: '产品机型', fProp: 'supplierNo' }
},
{
formType: 'FInput',
span: 12,
meta: { fLabel: '供应商代码', fProp: 'caseNo' }
},
{
formType: 'FInput',
formProp: 'issueDescribe',
span: 24,
meta: {
fLabel: '问题描述',
fProp: 'issueDescribe',
type: 'textarea'
}
},
{
formType: 'FInput',
span: 24,
meta: { fLabel: '责任SQI/SQE/SPM', fProp: 'caseNo' }
}
],
form: {
expandNo: '',
supplierName: '',
supplierNo: '',
caseNo: '',
issueDescribe:''
}
},