el-form 二次封装

56 阅读1分钟
  1. component

Form.vue

<template>
  <el-form
    ref="ruleFormRef"
    style="max-width: 600px"
    :model="modelValue"
    label-width="auto"
    class="demo-ruleForm"
    status-icon
    :rules="rules"
  >
    <el-form-item
      v-for="(item, index) in formItem"
      :label="item.label"
      :prop="item.prop"
      :key="index"
    >
      <templace v-if="item.type === 'input'">
        <el-input
          :placeholder="item.placeholder"
          v-model="modelValue[item.prop]"
        />
      </templace>
      <templace v-else-if="item.type === 'radio'">
        <el-radio-group v-model="modelValue[item.prop]">
          <el-radio
            v-for="item1 in item.typeInfo"
            :value="item1.value"
            :key="item1.value"
            >{{ item1.label }}</el-radio
          >
        </el-radio-group>
      </templace>
      <templace v-else-if="item.type === 'select'">
        <el-select
          v-model="modelValue[item.prop]"
          :placeholder="item.placeholder"
          :style="`width:${item.width}`"
        >
          <el-option
            v-for="item1 in item.optionsInfo"
            :key="item1.value"
            :label="item1.label"
            :value="item1.value"
          />
        </el-select>
      </templace>
    </el-form-item>

    <el-form-item v-if="btnList">
      <el-button
        v-for="item in btnList"
        :key="item.label"
        :type="item.type"
        @click="item.clickFn()"
      >
        {{ item.title }}
      </el-button>
    </el-form-item>
  </el-form>
</template>
<script setup>
import { computed } from "vue";
const props = defineProps({
  modelValue: Object,
  formItem: Array,
  btnList: Array,
});

const rules = computed(() => {
  return props.formItem.reduce((rulesObj, item) => {
    if (item.rules) {
      rulesObj[item.prop] = item.rules;
    }
    return rulesObj;
  }, {});
});
</script>
  1. 使用组件

在App.vue中使用

<template>
  <Form
    :btnList="btnList"
    :modelValue="modelValue"
    :formItem="formItem"
    size="large"
  ></Form>
</template>

<script setup>
import Form from "@/components/Form.vue";
import { reactive } from "vue";

const modelValue = reactive({
  id: 1,
  age: 18,
  name: "zs",
  sex: 1,
});
const formItem = [
  {
    prop: "id",
    label: "id",
    type: "input",
    placeholder: "请输入序号",
  },
  {
    prop: "age",
    label: "年龄",
    type: "input",
    placeholder: "请输入年龄",
  },
  {
    prop: "name",
    label: "姓名",
    type: "input",
    placeholder: "请输入姓名",
    rules: [{ required: true, message: "请输入姓名", trigger: "blur" }],
  },
  {
    prop: "sex",
    label: "性别",
    type: "radio",
    placeholder: "请选择性别",
    typeInfo: [
      { label: "男", value: 1 },
      { label: "女", value: 0 },
    ],
  },
  {
    prop: "option",
    label: "下拉框",
    type: "select",
    placeholder: "请选择option",
    width: "120px",
    optionsInfo: [
      {
        value: "Option1",
        label: "Option1",
      },
      {
        value: "Option2",
        label: "Option2",
      },
      {
        value: "Option3",
        label: "Option3",
      },
      {
        value: "Option4",
        label: "Option4",
      },
      {
        value: "Option5",
        label: "Option5",
      },
    ],
  },
];

const btnList = [
  {
    label: "cancel",
    type: "",
    title: "取消",
    clickFn: () => {
      console.log("取消");
    },
  },
  {
    label: "confirm",
    type: "primary",
    title: "确定",
    clickFn: () => {
      console.log("确定");
    },
  },
];
</script>

<style>
</style>