Vue elementui select选择器 全选功能 带搜索(左匹配)

740 阅读1分钟
<template>
  <el-select
    v-model="valuesList"
    multiple
    collapse-tags
    filterable
    :filter-method="filterValue"
    @change="selectAll"
    @focus="focus"
    @clear="clearAll"
    placeholder="请选择"
  >
    <el-option
      v-for="item in options"
      :key="item.value"
      :label="item.label"
      :value="item.value"
    >
    </el-option>
  </el-select>
</template>

<script>
export default {
  data() {
    return {
      valuesList: [],
      oldValues: [],
      currentVal: "",
      options: [
        {
          value: "0",
          label: "全选"
        },
        {
          value: "1",
          label: "黄金糕"
        },
        {
          value: "2",
          label: "双皮奶"
        },
        {
          value: "选项3",
          label: "蚵仔煎"
        },
        {
          value: "3",
          label: "龙须面"
        },
        {
          value: "4",
          label: "北京烤鸭"
        }
      ],
      optionsCopy: [
        {
          value: "0",
          label: "全选"
        },
        {
          value: "1",
          label: "黄金糕"
        },
        {
          value: "2",
          label: "双皮奶"
        },
        {
          value: "选项3",
          label: "蚵仔煎"
        },
        {
          value: "3",
          label: "龙须面"
        },
        {
          value: "4",
          label: "北京烤鸭"
        }
      ]
    };
  },
  methods: {
    selectAll(val) {
      const valArr = [];
      this.optionsCopy.forEach(item => {
        valArr.push(item.value);
      });
      // 全选
      if (val.includes("0")) {
        this.valuesList = valArr;
        this.oldValues = valArr;
      }
      // 点击其他取消全选
      if (val.includes("0") && val.length === this.options.length - 1) {
        if (val[0] === "0") {
          const duplicatedValues = [...new Set(this.valuesList)]
            .filter(item => val.includes(item))
            .splice(1);
          this.valuesList = duplicatedValues;
          this.oldValues = [];
        }
      }
      // 反选
      if (val.length === this.oldValues.length - 1 && !val.includes("0")) {
        this.valuesList = [];
        this.oldValues = [];
      }
      // 当其他全部选择时全选
      if (
        this.valuesList.length === this.options.length - 1 &&
        this.oldValues.length === 0
      ) {
        this.valuesList.unshift("0");
        this.oldValues = this.valuesList;
      }
      // 选择搜索出的结果后
      if (this.options.length < this.optionsCopy.length) {
        if (val[0] === "0") {
          const duplicatedValues = [...new Set(this.valuesList)]
            .filter(item => val.includes(item))
            .splice(1);
          this.valuesList = duplicatedValues;
          this.oldValues = [];
        }
        if (
          this.valuesList.length === this.optionsCopy.length &&
          this.oldValues.length === 0
        ) {
          this.valuesList.unshift("0");
          this.oldValues = this.valuesList;
        }
      }
    },
    // 搜索过滤方法
    filterValue(currentVal) {
      if (currentVal.length > 0) {
        this.options = this.optionsCopy.filter(item => {
          if (currentVal === item.label.substring(0, currentVal.length)) {
            return true;
          }
        });
        this.currentVal = currentVal;
      } else {
        this.options = this.optionsCopy;
        this.currentVal = "";
      }
    },
    // 聚焦时
    focus() {
      if (this.currentVal.length > 0) {
        this.options = this.optionsCopy.filter(item => {
          if (
            this.currentVal === item.label.substring(0, this.currentVal.length)
          ) {
            return true;
          }
        });
        return;
      } else {
        this.options = this.optionsCopy;
      }
      if (this.currentVal) {
        this.options = this.optionsCopy;
      }
    },
    clearAll() {
      this.valuesList = [];
      this.oldValues = [];
    }
  }
};
</script>

如图显示

image.png