解决el-autocomplete组件远程搜索的区间匹配问题

前言

el-autocompleteelement 中一个常用的组件,用于实现输入框自动完成的功能。然而,它的默认配置在远程搜索时存在一个问题:无法进行区间匹配。换句话说,即使输入的关键词是某个选项的子串或关键词的子串,也无法正确地搜索到该选项。本文将告诉你如何解决这个问题,实现更智能的 el-autocomplete 远程搜索功能。


未调整之前示例

在这里插入图片描述

可以看到当我搜索一个值的区间时,直接就搜索不出来了,那要怎么实现区间也可以搜索出来呢,其实关键在于 createStateFilter 方法。

默认的 createStateFilter 方法

createStateFilter(queryString) {
    
    
  return (state) => {
    
    
    return (
      state.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
    );
  };
},

要实现区间也可以搜索出来,你需要对 createStateFilter 方法进行修改。当前的实现是对输入的字符串与站点名称的前缀进行匹配,所以只能搜索到名称的开头部分。下面我们将 createStateFilter 方法的逻辑进行修改。


解决方法1:

这种方法对输入的字符串与站点名称进行了简单的包含关系的匹配,只要输入的字符串是站点名称的子串,即可进行搜索。这种方法的优点是简单直接,实现起来比较容易,对于一些较小规模的搜索需求可能足够。

缺点:

匹配精度较低:只要输入的字符串是站点名称的子串,即可进行搜索,无法实现更精确的区间匹配。
对于多个关键词的搜索支持不完善:如果输入的字符串包含多个关键词,这个方法无法实现对每个关键词都进行搜索的逻辑。

createStateFilter(queryString) {
    
    
  return (state) => {
    
    
    return (
     state.value.toLowerCase().indexOf(queryString.toLowerCase()) !== -1
    );
  };
},

解决方法2:

这种方法提供了更智能的搜索功能。它能够实现关键词与站点名称的区间匹配,支持多个关键词的搜索。

优点:

更精确的匹配:可以实现关键词的区间匹配,即使关键词不是站点名称的开头部分也可以搜索到。
支持多关键词搜索:可以处理输入字符串包含多个关键词的情况,保证每个关键词都能进行匹配。

createStateFilter(queryString) {
    
    
  return (state) => {
    
    
    const stationName = state.value.toLowerCase();
    queryString = queryString.toLowerCase();
    if (stationName.indexOf(queryString) !== -1) {
    
    
      // 如果输入的字符串是站点名称的子串,则可以进行搜索
      return true;
    }
    const stationNameArr = stationName.split(" ");
    const queryStringArr = queryString.split(" ");
    for (let i = 0; i < stationNameArr.length; i++) {
    
    
      if (
        queryStringArr.every(
          (query) => stationNameArr[i].indexOf(query) !== -1
        )
      ) {
    
    
        // 如果输入的字符串的每个关键词都在站点名称中找到了对应的子串,则可以进行搜索
        return true;
      }
    }
    return false;
  };
},

综上所述,两种方法都可以实现这个需求,如果你仅需简单的搜索功能,并且对搜索精度要求不高,那么第一种方法足够简单且有效。但如果你需要实现更智能的搜索,具备区间匹配功能和多关键词搜索支持,那么第二种方法更为适合。可以根据自身的具体需求,选择使用哪种方法。


完整代码

<template>
  <div>
    <el-autocomplete v-model="state" clearable :fetch-suggestions="querySearchAsync" placeholder="请输入内容" @select="handleSelect">
    </el-autocomplete>
  </div>
</template>
<script>
export default {
      
      
  data() {
      
      
    return {
      
      
      restaurants: [
        {
      
       value: "北京省市辖区东城区", address: "1" },
        {
      
       value: "河南省郑州市二七区", address: "2" },
        {
      
       value: "辽宁省沈阳市大东区", address: "3" },
        {
      
       value: "四川省成都市锦江区", address: "4" },
        {
      
       value: "海南省三亚市天涯区", address: "5" },
        {
      
       value: "浙江省杭州市余杭区", address: "6" },
      ],
      state: "",
      timeout: null,
    };
  },
  methods: {
      
      
    querySearchAsync(queryString, cb) {
      
      
      var restaurants = this.restaurants;
      var results = queryString
        ? restaurants.filter(this.createStateFilter(queryString))
        : restaurants;

      clearTimeout(this.timeout);
      this.timeout = setTimeout(() => {
      
      
        cb(results);
      }, 500 * Math.random());
    },
    createStateFilter(queryString) {
      
      
      return (state) => {
      
      
        const stationName = state.value.toLowerCase();
        queryString = queryString.toLowerCase();
        if (stationName.indexOf(queryString) !== -1) {
      
      
          // 如果输入的字符串是站点名称的子串,则可以进行搜索
          return true;
        }
        const stationNameArr = stationName.split(" ");
        const queryStringArr = queryString.split(" ");
        for (let i = 0; i < stationNameArr.length; i++) {
      
      
          if (
            queryStringArr.every(
              (query) => stationNameArr[i].indexOf(query) !== -1
            )
          ) {
      
      
            // 如果输入的字符串的每个关键词都在站点名称中找到了对应的子串,则可以进行搜索
            return true;
          }
        }
        return false;
      };
    },
    handleSelect(item) {
      
      
      console.log(item, "选择数据");
    },
  },
};
</script>

调整之后

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Shids_/article/details/132318739