二次封装el-form--只需配置文件

 兄弟们经过我上班摸鱼,最近摸了很多组件,一点点分享给大家。大佬们就别看了,二次封装很简单哦。我是根据element+封装的。大家在封装时,根据文档的api一步步实现。我给大家说说简单的思路。具体代码请看:https://gitee.com/liu--zicheng/vue3-vite-template/blob/master/src/components/ui/ZcForm.vue

其中也有table封装,包括搜索栏一键生成0。 

 <el-form-item label="Password" prop="pass">
      <el-input v-model="ruleForm.pass" type="password" autocomplete="off" />
    </el-form-item>
    <el-form-item label="Confirm" prop="checkPass">
      <el-input
        v-model="ruleForm.checkPass"
        type="password"
        autocomplete="off"
      />
    </el-form-item>

根据上面代码,大家来找相同的部分,然后通过配置的形式传入即可,是不是很简单。下面给大家分享我的配置文件。

 

import { formConfig } from "./../../../config/formConfig";

export const FormConfig = formConfig({
  formItems: [
    {
      label: "表单1",
      type: "number",
      otherOptions: {
        placeholder: "请输入账号",
      },
      prop: "account",
      rules: [
        {
          required: true,
          message: "请输入账号",
          trigger: "change",
        },
        {
          validator: (rule, value, callback) => {
            console.log("....", typeof value);
            if (value.length < 3 && value.length > 1) {
              callback(new Error("请输入长度大于3"));
            }
          },
          trigger: "change",
        },
      ],
    },
    {
      label: "表单2",
      type: "password",
      prop: "password",
      otherOptions: {
        placeholder: "请输入密码",
      },
      rules: [{ required: true, message: "请输入密码" }],
    },
    {
      label: "表单3",
      type: "datepicker",
      otherOptions: {
        startPlaceholder: "开始时间",
        endPlaceholder: "结束时间",
        type: "daterange",
        "unlink-panels": true,
        // disabled: true,
      },
      prop: "date",
      rules: [{ required: true, message: "请选择日期" }],
    },

    {
      label: "表单4",
      type: "select",
      otherOptions: {
        placeholder: "请选择部门",
        clearable: true,
        multiple: true,
      },
      prop: "dep",
      valueEnum: {
        1: "部门1",
        2: "部门2",
        3: "部门3",
        4: "部门4",
        5: "部门5",
        6: "部门6",
      },
      rules: [{ required: true, message: "请选择", trigger: "blur" }],
      width: 100,
    },
  ],
  labelWidth: "100px",
  //   itemColLayout: {
  //     // span: 8,
  //   },
  //   itemStyle: {
  //     padding: "",
  //   },
});

 这个配置文件,组件不需要动,除非有情况没有考虑,或者代码不严谨。大家可以根据情况书写自己的组件。

然后看看组件内部写法。

 

<template>
  <el-form ref="ruleFormRef" :model="form" :label-width="labelWidth">
    <el-row>
      <template v-for="item in formItems">
        <el-col v-bind="itemColLayout">
          <el-form-item
            :label="item.label"
            :prop="item.prop"
            :style="itemStyle"
            :rules="item.rules"
          >
            <el-input
              v-if="item.type == 'number'"
              v-model="form[`${item.prop}`]"
              :type="item.type"
              v-bind="item.otherOptions"
              onkeypress="return /[\d]/.test(String.fromCharCode(event.keyCode))"
            />
            <el-input
              v-if="item.type == 'input' || item.type == 'password'"
              v-model="form[`${item.prop}`]"
              :type="item.type"
              :show-password="item.type === 'password'"
              v-bind="item.otherOptions"
            />
            <el-select
              v-if="item.type == 'select'"
              v-model="form[`${item.prop}`]"
              v-bind="item.otherOptions"
              style="width: 100%"
            >
              <el-option
                v-for="option in item.valueEnum"
                :key="option"
                :label="item.valueEnum[option]"
                :value="option"
              ></el-option>
            </el-select>

            <el-date-picker
              v-if="item.type == 'datepicker'"
              v-model="form[`${item.prop}`]"
              v-bind="item.otherOptions"
            ></el-date-picker>
          </el-form-item>
        </el-col>
      </template>
    </el-row>
    <div class="footer">
      <slot name="footer">
        <el-button type="primary" @click="resetBtnClick">重置</el-button>
        <el-button type="primary" @click="searchBtnClick(ruleFormRef)"
          >提交</el-button
        >
      </slot>
    </div>
  </el-form>
</template>

<script setup lang="ts">
import { RuleItem } from "async-validator";
import { FormInstance } from "element-plus";
import { StyleValue } from "vue";
const ruleFormRef = ref<FormInstance>();
interface FormItems {
  label?: string;
  type?: string;
  placeholder?: string;
  rules?: RuleItem;
  prop?: string;
  valueEnum?: Object;
  clearable?: boolean;
  disabled?: boolean;
  multiple?: boolean;
  width?: number;
  otherOptions?: any;
}
const props = withDefaults(
  defineProps<{
    formItems: Array<FormItems | any>;
    labelWidth?: string;
    itemColLayout?: object;
    itemStyle?: StyleValue;
    request?: any;
  }>(),
  {
    labelWidth: "120px",
    itemColLayout: () => ({
      xl: 6, // >=1920px
      lg: 8, // >=1200px
      md: 12, // >=992px
      sm: 24, // >=768px
      xs: 24, // <768px
    }),
    itemStyle: () => ({
      padding: "0",
    }),
  }
);
const formParams = computed(() => {
  let params: any = {};
  props.formItems.map((item) => {
    params[item.prop] = "";
  });
  return params;
});
const form = reactive({ ...formParams.value });

// 提交按钮
const searchBtnClick = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  await formEl.validate((valid, fields) => {
    if (valid) {
      console.log("submit!", form);
      props.request(form);
    } else {
      console.log("error submit!", valid, fields);
    }
  });
};
// 重置按钮
const resetBtnClick = () => {
  ruleFormRef.value?.resetFields();
};
</script>

<style scoped lang="scss">
.footer {
  text-align: right;
}
</style>

Vue3中,`el-form`是Element UI提供的表单组件,为了提高代码复用性和灵活性,我们可以对其进行二次封装二次封装通常是将原生组件抽取成自定义的Vue组件,并提供更简洁、易用的API。 步骤大致如下: 1. **导入基础组件**:首先要在项目中安装Element UI库,并引入`ElForm`组件。 ```js import { ElForm } from 'element-plus'; ``` 2. **创建组件模板**:创建一个新的Vue组件文件,如`CustomForm.vue`,并设置基本结构,包括`form`属性用于接收外部传入的数据。 ```html <template> <el-form ref="customForm" :model="form" :rules="rules"> <!-- 根据实际求添加表单元素 --> </el-form> </template> ``` 3. **数据绑定和生命周期钩子**:在组件内部,通过`ref`获取到`el-form`实例,处理表单提交、验证等操作。同时可以添加`watch`监听数据变化,以及`mounted`等生命周期钩子。 ```js <script> export default { props: { form: { type: Object, required: true, }, rules: { type: Object, // ... 规则配置 }, }, setup(props) { const customFormRef = ref(null); onMounted(() => { customFormRef.value.validate(); }); // 添加事件处理器 watch( () => props.form, (newData) => { customFormRef.value.setFieldsValue(newData); }, { deep: true } ); return { customFormRef, }; }, }; </script> ``` 4. **对外暴露API**:提供一些方法供外部使用,比如提交表单、校验表单等。 ```js // 在methods中定义方法 export default { methods: { handleSubmit() { this.customFormRef.value.submit(); }, handleValidate() { this.customFormRef.value.validate(); }, }, }; ``` 5. **使用组件**:在其他地方引用并使用自定义的`CustomForm`组件,传递所的数据和规则。 ```vue <template> <CustomForm :form="myFormData" :rules="validationRules" @submit="handleSubmit" ></CustomForm> </template> <script> import CustomForm from '@/components/Common/CustomForm'; export default { components: { CustomForm, }, data() { return { myFormData: {}, validationRules: {}, }; }, methods: { // 使用自定义方法 }, }; </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

成序猿@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值