element二次封装el-select支持模糊搜索

夏侯嘉荣
2023-12-01

el-select封装

1.首先安装pinyin-match插件

// 安装 pinyin-match
 npm install pinyin-match --save

2.封装组件方便后期使用

<!--
 * @Descripttion: 二次封装支持模糊音搜索el-select--全局组件
 * @Author: JayShen
 * @Date: 2021-04-21 17:09:08
 * @LastEditors: JayShen
 * @LastEditTime: 2021-04-22 17:13:42
-->
<template>
  <el-select
    v-bind:value="value"
    v-bind="$attrs"
    v-on="$listeners"
    :placeholder="$attrs.placeholder"
    :filter-method="handleFilter"
    @focus="clearSelect"
    @clear="clearSelect"
    filterable
    clearable
    size="small"
  >
    <el-option
      v-for="item in optionsList"
      :key="item[props.value]"
      v-bind="$attrs"
      :label="item[props.label]"
      :value="item[props.value]"
    >
    </el-option>
  </el-select>
</template>

<script>
import PinyinMatch from "pinyin-match";
export default {
  name: "SearchSelect",
  model: {
    prop: "value",
    event: "input",
  },
  props: {
    // 需要绑定的值 等于 v-model
    value: {
      type: [String, Number],
      default: "",
    },
    // 需要循环的数组 必传
    options: {
      type: Array,
      default() {
        return [];
      },
      required: true,
    },
    // el-option参数 必传
    props: {
      type: Object,
      default() {
        return {
          value: "value",
          label: "label",
        };
      },
      required: true,
    },
  },
  data() {
    return {
      optionsList: [],
      copyOptionsList: [],
    };
  },
  watch: {
    // 监听赋值并copy一份
    options(val) {
      this.optionsList = val;
      this.copyOptionsList = JSON.parse(JSON.stringify(val));
    },
  },
  methods: {
    /**
     * @Description: 下拉框支持模糊搜索
     * @Author: JayShen
     * @param {*} val
     */
    handleFilter(val) {
      try {
        if (val) {
          this.optionsList = this.copyOptionsList;
          this.optionsList = this.optionsList.filter((item) =>
            PinyinMatch.match(item[this.props.label], val)
          );
        } else {
          this.optionsList = this.copyOptionsList;
        }
      } catch (error) {
        console.error("模糊音下拉框:", error);
      }
    },
    /**
     * @Description: clear、focus事件还原数组
     * @Author: JayShen
     * @param {*}
     */
    clearSelect() {
      this.optionsList = this.copyOptionsList;
    },
  },
};
</script>

3.在页面中使用

<SearchSelect
v-model="postData.id"
:options="list"
:props="{
   label: 'name',
   value: 'id'
}"
placeholder="请选择客服"
/>

组件内部增加了v-on="$listeners",包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器,在组件中就可以自己增加el-select的事件了。

 类似资料: