Ant Design of Vue Select框可搜索、可输入值组件封装,Vue2

126 阅读1分钟

效果图:

  • 正常搜索选择 image.png image.png

  • 英文搜索 image.png

  • 输入其他值并获取值input image.pngimage.png

模拟数据为【roleType】下面的selectOptions即为roleType

const selectOptions = [
    {
        "value": 0,
        "label": "系统",
        "meta": "system"
    },
    {
        "value": 1,
        "label": "医院",
        "meta": "hospital"
    },
    {
        "value": 2,
        "label": "科室",
        "meta": "departments"
    },
    {
        "value": 3,
        "label": "医生",
        "meta": "doctor"
    }
]

组件使用:

  <SelectInput
   :restQuery="['meta']"
   show-search
   filterOption
   :selectOptions="roleType"
   allowClear
   placeholder="请输入或选择角色分组"
   v-model="selectValue"/>
   
  // 查看值的btn
   <a-button @click="cli"> 点击查看值 </a-button>
   //就只是查看值
   cli() {
      console.log(this.selectValue, 'selectValue');
   },
   

组件代码:

<template>
  <a-select
    @blur="handleBlur"
    @search="handleSearch"
    @change="handleChange"
    @select="handleSelect"
    :value="$attrs.value"
    :filterOption="_filterOption()"
    class="select-input"
    v-bind="$attrs"
  >
    <a-select-option
      v-for="item in selectOptions"
      :key="item[valueLabel[0]]"
      :value="item[valueLabel[0]]"
    >
      {{ item[valueLabel[1]] }}
    </a-select-option>
  </a-select>
</template>
<script>
export default {
  name: "SlectInput",
  data() {
    return {
      value: undefined, //选中的值
      inputValue: undefined, // 输入的值
    };
  },
  props: {
    selectOptions: {
      type: Array,
    },
    // 另外检索字段
    restQuery: {
      type: Array,
      default: () => [],
    },
    valueLabel: {
      type: Array,
      default: () => ["value", "label"],
    },
  },
  methods: {
    _filterOption() {
      const { filterOption } = this.$attrs;
      if (filterOption === undefined) {
        return () => {};
      } else {
        return this.filterOption;
      }
    },
    filterOption(input, option) {
      let typeValue = this.selectOptions.find((i) => {
        return option.componentOptions.children[0].text.trim() === i[this.valueLabel[1]];
      });
      return (
        option.componentOptions.children[0].text
          .toLowerCase()
          .indexOf(input.toLowerCase()) >= 0 ||
        this.restQuery.some((key) => {
          return typeValue && typeValue[key] ? typeValue[key].includes(input) : false;
        })
      );
    },
    handleSearch(value) {
      if (this.value !== undefined) {
        this.value = undefined;
        this.$emit("input", this.value);
      }
      if (value) {
        this.inputValue = value;
      }
    },
    handleSelect(value) {
      this.value = value;
      this.$emit("input", value);
    },
    handleChange(value) {
      if (value === undefined) {
        this.value = value;
        this.inputValue = value;
        this.$emit("input", value);
      }
    },
    handleBlur() {
      const findValue = this.selectOptions.find(item => item[this.valueLabel[1]] === this.inputValue);
      if (findValue) {
        this.value = findValue[this.valueLabel[0]];
      }
      if (this.value !== undefined) {
        this.inputValue = undefined;
        this.$emit("input", this.value);
        return;
      }
      this.$emit("input", this.inputValue);
    },
  },
};
</script>
<style lang="scss" scoped>
.select-input {
  width: 180px;
}
</style>

**其实最简单的方法 改一个小东西就可以了 哈哈哈 mode="combobox"

       <a-select
          mode="combobox"
          style="width: 100%"
          placeholder=""
          allowClear
          show-search
          :filter-option="filterOption"
          v-model="value"
        >
          <a-select-option
            v-for="item in options"
            :key="item.value"
            >{{ item.label }}</a-select-option
          >
        </a-select>