Element UI el-form 表单封装思路

本文介绍了两种封装ElementUI表单的方法。一是通过在一个组件内使用v-if根据type动态展示不同类型的表单元素,如RadioGroup和Input。二是将每种表单类型分别封装为独立组件,然后在主文件中通过defineAsyncComponent异步引入并使用。这种方法有利于代码组织和复用。
摘要由CSDN通过智能技术生成

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 组件来进行使用。

效果如下

在这里插入图片描述

部分注意事项.

  1. 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:''
        }
      },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值