关于vue.js:只需一步让你的搜索框智能得起飞

35次阅读

共计 2529 个字符,预计需要花费 7 分钟才能阅读完成。

以前我总是这样过滤搜寻内容

data.filter(item => item.indexOf(keywords) >= 0)

这样的确能够满足关键字搜寻需要,但鉴于前端是间接出现画面给用户的人,咱们总是须要站在用户的角度去思考问题。前面我的项目做多了,其实发现这样在用户体验上并不够敌对,咱们来看下上面这个例子:

chrome 浏览器内编辑款式

vs code 内编辑款式

在 chrome 浏览器内无奈进行非间断的字符匹配,造成了一些体验感的缺失,而在 vs code 内却能够自在间断地输出关键字匹配。毫无疑问在 vs code 中咱们的编辑体验会更加晦涩,因为在很多场景下,咱们记不得一段间断的关键字,而是在断断续续的关键字,此时咱们应用这种间断的关键字进行搜寻能够很好地进步用户体验,而且也不影响间断的关键字搜寻。

什么场景下能够用非间断关键字搜寻

这类需要个别为搜寻本地数据时,且需要场景没有明确指定须要间断的关键字搜寻时,咱们都能够应用非间断关键字搜寻来实现,具体列举了以下几个场景:

  1. 树形菜单项搜寻:相似治理后盾页面的菜单、多节点搜寻
  2. checkbox 选项搜寻:选项较多的可搜寻 checkbox 内
  3. 门路列表搜寻:如 vs code 的文件搜寻
  4. 本地缓存搜寻:微信的缓存聊天记录关键字搜寻

接下来咱们探讨一下如何实现

得益于万能的npmjs.com,经验百般搜寻,我在下面找到了一个不错的 js 函数库实现了非间断关键字搜寻,咱们先看一个简略的 Demo,再分析一下它的实现原理。

js 库在此 -> string-discontinuous-match

此 Demo 中在 1000 条长度为 200 的随机字符串中非间断关键字搜寻,实现单次搜寻只须要 1 -2ms,性能可观。

接下来贴一下实现代码,通过 Vue 实现

<div id="app">
  <div class="search-wrap">
    <label>🔍</label>
    <input class="search-box" v-model="val" @input="inputHandler" />
  </div>
  <div class="info">
    <span>Data totals: {{numbers}}</span>
    <span v-if="performance">Performance: {{performance}}</span>
  </div>
  <div class="result">
    <span class="item" v-for="item in strings" :key="item" v-html="item"></span>
  </div>
</div>
// 初始状态
data() {
  return {
    val: '',
    strings: strings,  // strings 内蕴含 1000 条测试随机字符串
    numbers: strings.length,
    performance: '',
  };
}

以下为 input 事件实现

<input @input="inputHandler" />

import {discontinuousMatch, replaceMatchedString} from 'string-discontinuous-match';
function inputHandler() {
  // this.val 为搜寻关键字
  if (this.val) {let s = performance.now();
      let ret = discontinuousMatch(strings, this.val);
      let e = performance.now();
      this.strings = ret.map(item => {
        // 辅助函数 replaceMatchedString
        return replaceMatchedString(item, chars => `<span class="keyword">${chars}</span>`);
      });
      this.performance = (e - s) + 'ms';
    }
    else {
      this.data = strings;
      this.strings = strings;
      this.performance = '';
    }
    this.numbers = this.strings.length;
  }

搜寻后果格局为:

[
  {
    value: 'xxx',   // 被搜寻的字符串
    index: 0,       // 该项在数组中的索引
    
    // 匹配的关键字索引地位,如 [0, 2] 示意 value 中下标为 0 -2(蕴含 2)地位的字符,14 示意下标为 14 的单个字符。position: [[0, 2], [10, 12], 14, 17],
    lastIndex: 17   // 最初一个匹配的索引
  },
  // ...
]

所以你能够通过 position 信息去高亮对应地位的字符,但实际上你并不需要本人解决,string-discontinuous-match为咱们提供了一个辅助函数来解决它,例如在 inputHandler 函数中,你能够看到将匹配后果循环传入了 replaceMatchedString 函数中,它的作用是帮咱们提取匹配到的字符串,它依据 position 数组顺次触发回调,在 position: [[0, 2], [10, 12], 14, 17] 中会别离提取下标 0 到 2 的字符串,并触发一次回调,在回调中你能够返回转化后的字符串例如用 <span> 标签包裹它,接下来再提取 10 到 12 的字符串并触发回调,以此类推共计触发 4 次回调,最初把转化后的字符串返回给咱们,这样咱们就能够很不便地实现匹配关键字的高亮状态了。

通过这样一顿操作,就曾经实现了非间断关键字搜寻的性能了。

性能怎么样???

大家应该都会有这样的疑难,数据量小还好,但对于大数据量的匹配,会不会很慢呢?毕竟是非间断的匹配呢!!!
这个问题,此 js 库给出了这样的答复:

在 10000 个 5000 位随机字符串中搜寻 50 位随机要害字符串,疏忽大小写,花了101ms,性能好是不错的。

结尾

对于一个前端来说,咱们还是应该把用户体验放在重要的地位,而这个搜寻就是其中的优化点之一,只须要简略一步操作,咱们就能够解决此问题,不晓得正在看文章的你感觉是否值得一试呢?如果对这个 js 库感兴趣的能够自行钻研源码,其实它也很简略。
明天就到此啦,如有什么问题能够给作者去提 issue 哦。对我的教程感到称心,请不要悭吝你手中的收费赞赞哦!!!

正文完
 0