基于 el-select 二次封装远程查询

374 阅读1分钟
ui组件的二次封装的意义
  • 逻辑代码复用,接口对接只需对接一次,减少出错概率
  • ui组件库的快速切换:elementUI 到 ant-design-vue
<template>
  <el-select
    remote
    clearable
    filterable
    :value="value"
    :loading="loading"
    :remote-method="remoteMethod"
    v-bind="$attrs"
    v-on="$listeners"
    @change="onChangeHandle"
  >
    <el-option
      v-for="(item, index) in options"
      :key="`${index}#${item.value}`"
      :label="item.label"
      :value="item.value"
    ></el-option>
  </el-select>
</template>

<script>
export default {
  props: {
    value: {
      type: [String, Number, Array],
      default: ""
    },
    // 是否立即执行
    immediate: {
      type: Boolean,
      default: false
    },
    // 回显处理
    defaultOptions: {
      type: Array,
      default: null
    },
    // 获取接口函数 接受一个Promise对象
    remoteFunction: {
      type: [Promise, Function],
      required: true
    },
    // 请求拦截处理请求入参
    interceptRequest: {
      type: Function,
      default: null
    },
    // 响应拦截对请求数据进行二次处理
    interceptResponse: {
      type: Function,
      default: null
    }
  },
  data() {
    return {
      options: [],
      loading: false
    };
  },
  async mounted() {
    if (this.immediate) {
      await this.remoteMethod();
    }
  },
  watch: {
    defaultOptions: {
      immediate: true,
      handler(nV, oV) {
        (nV || []).forEach(item => {
          const option = this.options.find(opt => opt.value === item.value);
          if (!option) this.options.push(item);
        });
      }
    }
  },

  methods: {
    remoteMethod(val) {
      this.loading = true;
      const params = this.interceptRequest ? this.interceptRequest(val) : val;
      this.remoteFunction(params).then(data => {
        if (this.interceptResponse) {
          this.options = this.interceptResponse ? this.interceptResponse(data) : data;
        }
        this.loading = false;
      });
    },
    onChangeHandle(val) {
      if (this.$attrs.multiple === undefined || this.$attrs.multiple === false) {
        let entity = this.options.find(item => item.value === val);
        if (!entity && val !== "") {
          entity = {value: undefined, label: val};
        }
        this.$emit("mchange", val, entity);
        return;
      }
      const entitys = [];
      val.forEach(v => {
        let entity = this.options.find(item => item.value === v);
        if (!entity) {
          entity = {value: undefined, label: v};
        }
        entitys.push(entity);
      });
      this.$emit("mchange", val, entitys);
    }
  }
};
</script>