二次封装组件 - 表单el-form

        有时候常常需要二次封装一下Element UI里面的一些东西来满足开发是的一些需求,为了方便 快捷的适应开发,就封装了常用的组件之一中的表单

        由于个人水平比较菜,然后又想方便以后快速开发(其实就是想摸鱼)。最后🐟没摸成,还有点小费事。废话不多说,上代码:

// 模板部分
<el-form
  :label-width="formConfig.labelWidth"
  :label-position="formConfig.labelPosition"
  :ref="formConfig.ref"
  :model="formParams"
  :inline="formConfig.inline"
>
  <el-form-item
    :label="item.label"
    v-for="(item, index) in formDataList"
    :key="index"
    :prop="item.prop"
    :rules="item.rules"
  >
    <el-input
      v-if="item.type === 'input'"
      v-model="formParams[item.prop]"
      :placeholder="item.placeholder"
    ></el-input>
    <el-select
      v-if="item.type === 'select'"
      style="width: 100%"
      v-model="formParams[item.prop]"
      :placeholder="item.placeholder"
    >
      <el-option
        :label="opItem.label"
        :value="opItem.value"
        v-for="(opItem, index) in item.options"
        :key="index"
      ></el-option>
    </el-select>
    <el-date-picker
      v-if="item.type === 'date'"
      type="date"
      value-format="yyyy-MM-dd"
      style="width: 100%"
      v-model="formParams[item.prop]"
      :placeholder="item.placeholder"
    ></el-date-picker>
    <el-date-picker
      v-if="item.type === 'daterange'"
      type="daterange"
      value-format=“yyyy-MM-dd”
      style="width: 100%"
      start-placeholder="开始时间"
      end-placeholder="结束时间"
      v-model="formParams[item.prop]"
    ></el-date-picker>
    <el-radio-group
      v-if="item.type === 'radio'"
      v-model="formParams[item.prop]"
      :placeholder="item.placeholder"
    >
      <el-radio
        :label="opItem.label"
        v-for="(opItem, index) in item.options"
        :key="index"
        :rules="item.rules"
      ></el-radio>
    </el-radio-group>
    <el-input
      v-if="item.type === 'textarea'"
      type="textarea"
      v-model="formParams[item.prop]"
      :placeholder="item.placeholder"
    ></el-input>
    <el-switch
      v-if="item.type === 'switch'"
      v-model="formParams[item.prop]"
    ></el-switch>
  </el-form-item>
</el-form>

<div>
  <!-- 插槽、为了多变的存放操作按钮 -->
  <template>
    <slot name="operation"></slot>
  </template>
</div>

<script>
export default {
  /**
   * formDataList  表单数据
   * formParams   表单value /prop
   * formConfig   表单配置值
   */
  props: {
    formDataList: {
      type: Array,
      default: () => [],
    },
    formParams: {
      type: Object,
      default: () => {},
    },
    formConfig: {
      type: Object,
      default: () => {},
    }
  },
  methods: {
    // 从外部验证表单是否必填项满足条件
    validated(callback) {
      this.$refs[this.formConfig.ref].validate((valid) => {
        callback();
      });
    },
    // 将子组件的表单内容传递给父表单
    transferData() {
      return new Promise((resolve, reject) => {
        this.$refs[this.formConfig.ref].validate((valid) => {
          if (valid) {
            resolve(this.formParams);
          } else {
            reject("err");
          }
        });
      });
    },
  },
};
</script>

        其中在使用validated,transferData 这两个方法在使用的时候切记、切记:父组件一定要有一个跟子组件一样的ref值,不然的话是无效的

就像下面这样去调用组件:

<template>
  <div class="content">
       <!--  如果父组件想要使用子组件中的transferData、validated方法去获取或是验证表单的内容,就要加上ref,且值跟子组件的ref一定要一直,不然没用的 --> 
      <ContentFrom
        :formDataList="formDataList"
        :formParams="formParams"
        :formConfig="formConfig"
        :formType="formType"
        :ref="formConfig.ref"
      >
        <template slot="operation">
          <el-button type="warning" @click="commitData">提交</el-button>
          <el-button type="primary" @click="resetInfo">重置</el-button>
        </template>
      </ContentFrom>
  </div>
</template>
<script>
import ContentFromfrom "@/components/ContentFrom.vue";

export default {
  name: "content",
  components: {
    ContentFrom
  },
  data() {
    return {
      formParams: {
        address: "", 
        level: ""
      },
      formDataList: [
        {
          label: "地区",
          prop: "address",
          type: "input",
          placeholder: "请输入地区",
          rules: [{ required: true }],
        },
        {
          label: "水平",
          prop: "level",
          placeholder: "请输入水平",
          type: "input",
        }
      ],
      formConfig: {
        labelWidth: "100px",
        inline: true,
        ref: "formRef",
        labelPosition: "right",
      }
    };
  },
  methods: {
    resetInfo() {
      this.formParams = {};
    },
    commitData() {
      // 这样就可以获取子组件中的表单数据啦
      this.$refs[this.formConfig.ref].transferData().then((date) => {
        console.log(date);
      });
    },
  },
};
</script>

        其实在封装的时候想让这个表单可以运用到多个场景中(就类似常规的表单收集,搜索框之类的。呃……后面确实也是实现了(就是在每次应用的时候传递一个固定的变量去判断给一个不同的样式,差不多就可以实现想要的效果),但是最后的结果有点小崩,就是感觉表单一整个封装就在使用的时候很不友好。其实是有点纠结表单到底是统一封装好一点还是分开封装好一点(不封装的话,没什么比较独特的地方😅)

        真希望有个大佬可以带带我这个菜鸡[向往.jpg]……

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

BlackStar-Coder

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

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

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

打赏作者

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

抵扣说明:

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

余额充值