vue2使用 <component> 标签动态渲染不同的表单组件
在后台管理系统中,涉及到大量表单信息的修改和新增。现在想对模板中代码做一些简单的优化。
1. 使用 v-for
循环简化表单项
可以将表单项的定义提取到一个数组中,然后使用 v-for
循环来生成这些表单项。这将减少重复代码,提高可维护性。
2. 统一样式和属性
如果多个表单项使用相同的样式或属性,可以考虑将这些样式和属性提取到一个对象中,以便于管理。
3. 使用计算属性
对于一些简单的逻辑,比如根据 editForm.type
显示不同的文本,可以使用计算属性来简化模板中的逻辑。
原代码
<el-form
ref="editForm"
:model="editForm"
:rules="rules"
:inline="true"
label-width="115px"
size="small"
>
<el-form-item :size="size" label="投放物料:" prop="materialName">
<el-input
v-model="editForm.materialName"
class="editItem"
placeholder="请选择"
readonly
style="width: 300px"
>
<el-button
slot="append"
icon="el-icon-search"
@click="selectMaterial"
>
</el-button>
</el-input>
</el-form-item>
<el-form-item :size="size" label="物料单位:" prop="unitName">
<el-input
v-model="editForm.unitName"
class="editItem"
readonly
style="width: 100px"
>
</el-input>
</el-form-item>
<el-form-item :size="size" label="物料批号:" prop="batchNumber">
<el-input v-model="editForm.batchNumber" class="editItem" readonly>
</el-input>
</el-form-item>
<el-form-item :size="size" label="投放数量:" prop="quantity">
<el-input-number
v-model="editForm.quantity"
:precision="4"
:step="1"
:min="0"
class="editItem"
></el-input-number>
</el-form-item>
<el-form-item :size="size" label="投放时间:" prop="feedingTime">
<el-date-picker
v-model="editForm.feedingTime"
type="datetime"
placeholder="选择投放时间"
default-time="12:00:00"
value-format="yyyy-MM-dd HH:mm:ss"
class="editItem"
>
</el-date-picker>
</el-form-item>
<el-form-item :size="size" label="投放类型:" prop="type">
<el-select
disabled
v-model="editForm.type"
placeholder="请选择"
class="editItem"
>
<el-option
v-for="item in typeOption"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :size="size" label="流转单号:" prop="circulationNo">
<el-input
v-model="editForm.circulationNo"
style="width: 225px"
placeholder="请选择"
readonly
>
<el-button
slot="append"
icon="el-icon-search"
@click="selectCirculation"
></el-button>
</el-input>
</el-form-item>
<el-form-item :size="size" label="产品编码:">
<el-input v-model="editForm.code" readonly style="width: 225px">
</el-input>
</el-form-item>
<el-form-item :size="size" label="产品图号:">
<el-input
v-model="editForm.drawingNumber"
readonly
style="width: 150px"
>
</el-input>
</el-form-item>
<el-form-item :size="size" label="产品型号:">
<el-input v-model="editForm.model" class="editItem" readonly>
</el-input>
</el-form-item>
<el-form-item :size="size" label="产品规格:">
<el-input
v-model="editForm.specifications"
class="editItem"
readonly
>
</el-input>
</el-form-item>
<el-form-item :size="size" label="产品尺寸:">
<el-input v-model="editForm.size" class="editItem" readonly>
</el-input>
</el-form-item>
<el-form-item label="备注:" prop="remark">
<el-input
v-model="editForm.remark"
type="textarea"
placeholder="请输入备注"
style="width: 850px"
/>
</el-form-item>
<div style="clear: both"></div>
</el-form>
更改后
<el-form
ref="editForm"
:model="editForm"
:rules="rules"
:inline="true"
label-width="115px"
size="small"
>
<el-form-item
v-for="(item, index) in formItems"
:key="index"
:size="size"
:label="item.label"
:prop="item.prop"
>
<component
:is="item.component"
v-model="editForm[item.prop]"
v-bind="item.attrs"
class="editItem"
>
<template v-if="item.component === 'el-input'" #append>
<el-button
v-if="item.isSearch"
icon="el-icon-search"
@click="item.searchMethod"
></el-button>
</template>
</component>
</el-form-item>
<el-form-item label="备注:" prop="remark">
<el-input
v-model="editForm.remark"
type="textarea"
placeholder="请输入备注"
style="width: 850px"
/>
</el-form-item>
<div style="clear: both"></div>
</el-form>
js
data() {
return {
size: "small",
vis: false,
formItems: [
{
label: "投放物料:",
prop: "materialName",
component: "el-input",
attrs: {
placeholder: "请选择",
readonly: true,
style: { width: "300px" },
},
isSearch: true,
searchMethod: this.selectMaterial,
},
{
label: "物料单位:",
prop: "unitName",
component: "el-input",
attrs: {
readonly: true,
style: { width: "100px" },
},
},
{
label: "物料批号:",
prop: "batchNumber",
component: "el-input",
attrs: {
readonly: true,
},
},
{
label: "投放数量:",
prop: "quantity",
component: "el-input-number",
attrs: {
precision: 4,
step: 1,
min: 0,
},
},
{
label: "投放时间:",
prop: "feedingTime",
component: "el-date-picker",
attrs: {
type: "datetime",
placeholder: "选择投放时间",
defaultTime: "12:00:00",
valueFormat: "yyyy-MM-dd HH:mm:ss",
},
},
{
label: "投放类型:",
prop: "type",
component: "el-select",
attrs: {
disabled: true,
placeholder: "请选择",
},
},
{
label: "流转单号:",
prop: "circulationNo",
component: "el-input",
attrs: {
placeholder: "请选择",
readonly: true,
style: { width: "225px" },
},
isSearch: true,
searchMethod: this.selectCirculation,
},
{
label: "产品编码:",
prop: "code",
component: "el-input",
attrs: {
readonly: true,
style: { width: "225px" },
},
},
{
label: "产品图号:",
prop: "drawingNumber",
component: "el-input",
attrs: {
readonly: true,
style: { width: "150px" },
},
},
{
label: "产品型号:",
prop: "model",
component: "el-input",
attrs: {
readonly: true,
},
},
{
label: "产品规格:",
prop: "specifications",
component: "el-input",
attrs: {
readonly: true,
},
},
{
label: "产品尺寸:",
prop: "size",
component: "el-input",
attrs: {
readonly: true,
},
},
],
descriptionItems: [],
};
},
- 表单项数组:通过
formItems
数组定义表单项,使用v-for
循环生成表单项,减少了重复代码。 - 组件动态渲染:使用
<component>
标签动态渲染不同的表单组件,增强了灵活性。