阅读 1562

如何优雅的二次封装element组件

背景

项目上在搜索的时候,会用到DatePickertype="daterange" 版本:2.9.2

代码如下:

            <el-date-picker
              v-model="formData.putTime"
              type="daterange"
              align="right"
              unlink-panels
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              :default-time="['00:00:00', '23:59:59']"
              value-format="yyyy-MM-dd HH:mm:ss"
            >
            </el-date-picker>
复制代码

putTime是一个数组,而后台需要的参数分为putBeginTimeputEndTime 所以在进行请求之前还要

     params.putTime = params.putTime || [];
      params.putBeginTime = params.putTime[0];
      params.putEndTime = params.putTime[1];
      delete params.putTime;
复制代码

尤其是该组件的清空操作,putTime会被赋值为null 这样使用起来还是很不舒服的

二次封装

<template>
  <el-date-picker
    @change="onChange"
    v-model="list"
    v-bind="merageAttr"
    v-on="$listeners"
  >
  </el-date-picker>
</template>
<script>
export default {
  inject: ["elForm"],
  props: {
    startKey: String,
    endKey: String
  },
  data() {
    return {
      list: []
    };
  },
  computed: {
    merageAttr() {
      return {
        ...{
          type: "daterange",
          align: "right",
          "unlink-panels": true,
          "range-separator": "至",
          "start-placeholder": "开始日期",
          "end-placeholder": "结束日期",
          "default-time": ["00:00:00", "23:59:59"],
          "value-format": "yyyy-MM-dd HH:mm:ss"
        },
        ...this.$attrs
      };
    }
  },

  methods: {
    onChange(list) {
      list = list || [];
      this.elForm.model[this.startKey] = list[0];
      this.elForm.model[this.endKey] = list[1];
    }
  }
};
</script>
</script>
复制代码

From组件会通过provide的形式提供自身实例elForm,子组件可以通过inject获取

v-on="$listeners"merageAttr,可以保证组件有默认值的情况下,也能响应的外面的变化

想要覆盖"start-placeholder": "开始日期",外面传参也要使用start-placeholder,而不能是startPlaceholder

最后通过onChange解决参数的问题

2021-07-17

意外的发现,上述方式会导致$refs.form.resetFields()无法生效,看了一下源码

form.vue

resetFields() {
  if (!this.model) {
    console.warn('[Element Warn][Form]model is required for resetFields to work.');
    return;
  }
  this.fields.forEach(field => {
    field.resetField();
  });
},
复制代码

field.resetField 是在 form-item.vue 里,所以需要三步

第一步 el-form-item要加 prop

<el-form-item label="申请时间:" prop="createTime"></el-form-item>
复制代码

第二步 注入elFormItem

inject: ["elForm", "elFormItem"],
复制代码

第三步,覆盖elFormItemresetField方法

  mounted() {
    this.elFormItem.resetField = () => {
      this.list = [];
      this.elForm.model[this.startKey] = null;
      this.elForm.model[this.endKey] = null;
    };
  }
复制代码
文章分类
前端
文章标签