最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Fuse.js前端模糊搜索神器從入門到精通教程

 更新時間:2026年06月10日 08:20:29   作者:代碼貧困戶  
Fuse.js是一個輕量級JavaScript模糊搜索庫,適用于前端實現(xiàn)本地數(shù)據(jù)搜索功能,這篇文章主要介紹了Fuse.js前端模糊搜索神器從入門到精通的相關(guān)資料,需要的朋友可以參考下

本文將詳細(xì)介紹 Fuse.js 的使用方法,包含完整代碼示例和參數(shù)詳解。

前言

Fuse.js 是一個輕量級的 JavaScript 模糊搜索庫,無需依賴任何外部庫,支持瀏覽器和 Node.js 環(huán)境。它能夠根據(jù)關(guān)鍵詞對數(shù)據(jù)進(jìn)行模糊匹配,并返回匹配度分?jǐn)?shù)和匹配位置信息。

Fuse.js 應(yīng)用場景

1. 大屏列表搜索

場景: 數(shù)據(jù)大屏、管理后臺的表格搜索

// 用戶在大屏中搜索產(chǎn)品名稱
const fuse = new Fuse(products, { keys: ['name', 'code'], threshold: 0.3 })
// 實時過濾顯示匹配的產(chǎn)品

2. 離線文檔和知識庫

場景: 幫助中心、API 文檔、內(nèi)部知識庫

// 搜索技術(shù)文檔
const fuse = new Fuse(docs, { keys: ['title', 'content', 'tags'] })
// 用戶輸入"react hooks"即可找到相關(guān)文檔

3. 系統(tǒng)菜單導(dǎo)航

場景: 后臺管理系統(tǒng)的菜單快速定位

// 菜單搜索
const fuse = new Fuse(menus, {
  keys: ['name', 'path', 'description'],
  threshold: 0.4
})
// 輸入"用戶管理"或"user"都能找到用戶管理菜單

4. 實時搜索建議

場景: 搜索框的下拉建議

// 輸入時實時給出建議
const fuse = new Fuse(hotKeywords, { threshold: 0.2 })
const suggestions = fuse.search(query).slice(0, 5)

5. 電商商品搜索

場景: 商品列表模糊搜索

const fuse = new Fuse(products, {
  keys: ['name', 'brand', 'category', 'description'],
  threshold: 0.3,
  includeScore: true
})
// "耐克運動鞋"可以匹配到"Nike運動鞋"

6. 表單自動補全

場景: 地址輸入、聯(lián)系人選擇

const fuse = new Fuse(addresses, {
  keys: ['city', 'district', 'street'],
  ignoreLocation: true
})

7. 游戲內(nèi)搜索

場景: 游戲道具、技能、任務(wù)搜索

const fuse = new Fuse(gameItems, {
  keys: ['name', 'description'],
  threshold: 0.2
})

8. 企業(yè)級應(yīng)用

場景: CRM、ERP 系統(tǒng)中的客戶、訂單搜索

const fuse = new Fuse(customers, {
  keys: ['name', 'company', 'email', 'phone'],
  threshold: 0.3
})

9. 數(shù)據(jù)分析工具

場景: 報表、指標(biāo)、維度搜索

const fuse = new Fuse(metrics, {
  keys: ['name', 'description', 'tags'],
  threshold: 0.4
})

10. 移動端應(yīng)用

場景: App 內(nèi)的搜索功能

// 移動端通常需要更寬松的匹配
const fuse = new Fuse(data, {
  threshold: 0.5,  // 更寬松
  ignoreLocation: true
})

為什么選擇 Fuse.js?

優(yōu)勢

  • 零依賴: 純 JavaScript 實現(xiàn)
  • 輕量級: 體積小,性能好
  • 易用性: API 簡單直觀
  • 靈活性: 支持復(fù)雜配置
  • 功能強(qiáng)大: 支持高亮、排序、嵌套搜索

不適合的場景

  • 需要后端搜索(大數(shù)據(jù)量)
  • 需要模糊匹配圖片、音頻等二進(jìn)制數(shù)據(jù)
  • 需要復(fù)雜的 SQL 查詢

1. 安裝與引入

NPM 安裝

npm install fuse.js

CDN 引入

<script src="https://cdn.jsdelivr.net/npm/fuse.js@6.6.2"></script>

ES6 導(dǎo)入

import Fuse from 'fuse.js'

2. 基礎(chǔ)使用

2.1 簡單示例

// 1. 準(zhǔn)備數(shù)據(jù)
const books = [
  { title: 'JavaScript 高級程序設(shè)計', author: 'Nicholas C. Zakas' },
  { title: '深入理解 ES6', author: 'Nicholas C. Zakas' },
  { title: 'Vue.js 實戰(zhàn)', author: '梁灝' }
]

// 2. 創(chuàng)建 Fuse 實例
const fuse = new Fuse(books, {
  keys: ['title', 'author']
})

// 3. 搜索
const results = fuse.search('JavaScript')
console.log(results)

2.2 輸出結(jié)果

[
  {
    item: { title: 'JavaScript 高級程序設(shè)計', author: 'Nicholas C. Zakas' },
    refIndex: 0,
    score: 0.123,
    matches: [
      {
        key: 'title',
        value: 'JavaScript 高級程序設(shè)計',
        indices: [[0, 9]]  // 匹配位置:從0到9
      }
    ]
  }
]

3. 核心配置參數(shù)詳解

3.1 keys - 搜索字段

  • 類型: string[]
  • 默認(rèn)值: []
  • 說明: 指定要搜索的字段名,支持嵌套路徑
const options = {
  keys: ['title', 'author.name', 'tags']
}

3.2 threshold - 模糊度閾值

  • 類型: number
  • 默認(rèn)值: 0.6
  • 范圍: 0.0 - 1.0
  • 說明:
  • 0.0 = 完全匹配(嚴(yán)格)
  • 1.0 = 匹配任意內(nèi)容(寬松)
  • 推薦值:0.3 - 0.4
const options = {
  threshold: 0.3  // 適度模糊
}

3.3 includeScore - 包含匹配分?jǐn)?shù)

  • 類型: boolean
  • 默認(rèn)值: false
  • 說明: 是否在結(jié)果中包含匹配度分?jǐn)?shù)
const options = {
  includeScore: true
}

3.4 includeMatches - 包含匹配信息

  • 類型: boolean
  • 默認(rèn)值: false
  • 說明: 是否包含詳細(xì)的匹配位置信息(用于高亮)
const options = {
  includeMatches: true
}

3.5 minMatchCharLength - 最小匹配字符長度

  • 類型: number
  • 默認(rèn)值: 1
  • 說明: 搜索關(guān)鍵詞的最小字符數(shù)
const options = {
  minMatchCharLength: 2  // 至少2個字符才搜索
}

3.6 shouldSort - 結(jié)果排序

  • 類型: boolean
  • 默認(rèn)值: true
  • 說明: 是否按匹配度分?jǐn)?shù)排序(分?jǐn)?shù)低的在前)
const options = {
  shouldSort: true
}

3.7 useExtendedSearch - 擴(kuò)展搜索模式

  • 類型: boolean
  • 默認(rèn)值: false
  • 說明: 啟用后支持更多搜索語法
const options = {
  useExtendedSearch: true
}

// 使用擴(kuò)展搜索語法
fuse.search('\'exact match')  // 精確匹配
fuse.search('!term')          // 排除 term

3.8 ignoreLocation - 忽略位置

  • 類型: boolean
  • 默認(rèn)值: false
  • 說明: 是否忽略關(guān)鍵詞在文本中的位置
const options = {
  ignoreLocation: true  // 只要包含就匹配,不管位置
}

3.9 findAllMatches - 查找所有匹配

  • 類型: boolean
  • 默認(rèn)值: false
  • 說明: 是否查找所有匹配項(而不僅僅是第一個)
const options = {
  findAllMatches: true
}

3.10 includeScore - 分?jǐn)?shù)權(quán)重

  • 類型: boolean
  • 默認(rèn)值: false
  • 說明: 是否返回匹配分?jǐn)?shù)
const options = {
  includeScore: true
}

4. 完整配置示例

const options = {
  // 搜索閾值:0.0(嚴(yán)格)- 1.0(寬松)
  threshold: 0.3,

  // 包含匹配分?jǐn)?shù)
  includeScore: true,

  // 包含匹配信息(用于高亮)
  includeMatches: true,

  // 搜索字段
  keys: ['title', 'description', 'tags', 'category'],

  // 最小匹配字符長度
  minMatchCharLength: 1,

  // 是否排序
  shouldSort: true,

  // 忽略位置
  ignoreLocation: false,

  // 查找所有匹配
  findAllMatches: false,

  // 擴(kuò)展搜索模式
  useExtendedSearch: false
}

const fuse = new Fuse(data, options)

5. 實戰(zhàn)案例:Vue 3 組件

5.1 完整組件代碼

<template>
  <div class="search-demo">
    <h1>Fuse.js 模糊搜索演示</h1>

    <!-- 搜索輸入 -->
    <div class="search-box">
      <input
        v-model="searchQuery"
        placeholder="輸入關(guān)鍵詞搜索..."
        class="input"
      />

      <!-- 閾值控制滑塊 -->
      <div class="threshold-control">
        <label>模糊度: {{ threshold.toFixed(2) }}</label>
        <input
          type="range"
          v-model.number="threshold"
          min="0"
          max="1"
          step="0.05"
        />
        <span class="desc">{{ thresholdDescription }}</span>
      </div>

      <div class="stats">
        找到 {{ results.length }} 條結(jié)果(共 {{ items.length }} 條)
      </div>
    </div>

    <!-- 搜索結(jié)果 -->
    <div class="results" v-if="searchQuery">
      <div v-for="result in results" :key="result.item.id" class="result-item">
        <h3 v-html="highlight(result.item.title, result.matches, 'title')"></h3>
        <p v-html="highlight(result.item.description, result.matches, 'description')"></p>
        <div class="meta">
          <span class="category">{{ result.item.category }}</span>
          <span class="score">匹配度: {{ result.score.toFixed(2) }}</span>
        </div>
        <div class="tags">
          <span
            v-for="tag in result.item.tags"
            :key="tag"
            v-html="highlight(tag, result.matches, 'tags')"
          ></span>
        </div>
      </div>
    </div>

    <!-- 原始數(shù)據(jù) -->
    <div class="original" v-else>
      <h3>原始數(shù)據(jù)({{ items.length }} 條)</h3>
      <div v-for="item in items" :key="item.id" class="item">
        <h4>{{ item.title }}</h4>
        <p>{{ item.description }}</p>
        <div class="tags">
          <span v-for="tag in item.tags" :key="tag">{{ tag }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import Fuse from 'fuse.js'

export default {
  name: 'FuseDemo',
  data() {
    return {
      searchQuery: '',
      threshold: 0.3,
      items: [
        {
          id: 1,
          title: 'JavaScript 基礎(chǔ)教程',
          description: '學(xué)習(xí) JavaScript 的基礎(chǔ)知識,包括變量、函數(shù)和數(shù)據(jù)類型',
          category: '編程',
          tags: ['javascript', '基礎(chǔ)', '教程']
        },
        {
          id: 2,
          title: 'Vue.js 實戰(zhàn)技巧',
          description: 'Vue.js 實際項目中的高級技巧和最佳實踐分享',
          category: '前端',
          tags: ['vue', '實戰(zhàn)', '技巧']
        },
        {
          id: 3,
          title: 'Node.js 性能優(yōu)化',
          description: '如何優(yōu)化 Node.js 應(yīng)用程序的性能和內(nèi)存使用',
          category: '后端',
          tags: ['nodejs', '性能', '優(yōu)化']
        }
      ],
      fuse: null
    }
  },
  created() {
    this.initFuse()
  },
  watch: {
    threshold() {
      this.initFuse()  // 閾值改變時重新初始化
    }
  },
  computed: {
    // 閾值描述
    thresholdDescription() {
      if (this.threshold <= 0.1) return '精確匹配(嚴(yán)格)'
      if (this.threshold <= 0.3) return '適度模糊(推薦)'
      if (this.threshold <= 0.5) return '較模糊'
      if (this.threshold <= 0.7) return '很模糊'
      return '非常模糊(寬松)'
    },

    // 搜索結(jié)果
    results() {
      if (!this.searchQuery.trim()) return []
      return this.fuse.search(this.searchQuery.trim())
    }
  },
  methods: {
    // 初始化 Fuse
    initFuse() {
      const options = {
        threshold: this.threshold,
        includeScore: true,
        includeMatches: true,
        keys: ['title', 'description', 'tags', 'category'],
        minMatchCharLength: 1,
        shouldSort: true
      }
      this.fuse = new Fuse(this.items, options)
    },

    // 高亮文本
    highlight(text, matches, key) {
      if (!matches || matches.length === 0) return text

      const match = matches.find(m => m.key === key)
      if (!match || !match.indices) return text

      const indices = [...match.indices].sort((a, b) => a[0] - b[0])
      let result = ''
      let lastIndex = 0

      indices.forEach(([start, end]) => {
        if (start < lastIndex) return

        result += text.substring(lastIndex, start)
        result += `<span class="highlight">${text.substring(start, end + 1)}</span>`
        lastIndex = end + 1
      })

      result += text.substring(lastIndex)
      return result
    }
  }
}
</script>

<style scoped>
.search-demo {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}

.search-box {
  background: #f8f9fa;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
}

.input {
  width: 100%;
  padding: 12px 16px;
  font-size: 16px;
  border: 2px solid #ddd;
  border-radius: 6px;
  outline: none;
}

.input:focus {
  border-color: #42b983;
}

.threshold-control {
  margin-top: 15px;
  padding: 10px;
  background: white;
  border-radius: 6px;
}

.threshold-control input[type="range"] {
  width: 100%;
  margin: 8px 0;
}

.threshold-control .desc {
  color: #42b983;
  font-weight: bold;
  margin-left: 10px;
}

.stats {
  margin-top: 10px;
  color: #666;
  font-size: 14px;
}

.result-item, .item {
  background: white;
  border: 1px solid #e9ecef;
  border-radius: 6px;
  padding: 16px;
  margin-bottom: 12px;
}

.result-item h3, .item h4 {
  margin: 0 0 8px 0;
  color: #2c3e50;
}

.result-item p, .item p {
  margin: 8px 0;
  color: #555;
  line-height: 1.6;
}

.meta {
  display: flex;
  justify-content: space-between;
  margin-top: 8px;
  font-size: 13px;
}

.category {
  background: #e7f5ff;
  color: #1971c2;
  padding: 2px 8px;
  border-radius: 4px;
}

.score {
  color: #888;
  font-style: italic;
}

.tags {
  margin-top: 8px;
}

.tags span {
  display: inline-block;
  background: #42b983;
  color: white;
  padding: 3px 10px;
  border-radius: 12px;
  font-size: 11px;
  margin-right: 6px;
  margin-top: 4px;
}

/* 高亮樣式 */
:deep(.highlight) {
  background-color: #ff4444;
  color: white;
  padding: 2px 4px;
  border-radius: 3px;
  font-weight: bold;
}
</style>

fuse與傳統(tǒng)js搜索對比

1.精準(zhǔn)搜索

特性傳統(tǒng) JS 搜索(includes / RegExp)Fuse.js(模糊搜索引擎)
匹配精度全等匹配,錯一個字母就搜不到模糊匹配,允許拼寫錯誤、漏字
結(jié)果排序無序,通常按原數(shù)組順序排列相關(guān)性排序,最像的結(jié)果排在最前面
搜索深度需手寫邏輯處理嵌套對象支持路徑配置,直接配置 author.name
業(yè)務(wù)邏輯邏輯分散在各個 filter聲明式配置,通過權(quán)重、閾值統(tǒng)一控制

fuse可以通過調(diào)整模糊度擴(kuò)大搜索范圍,同一個搜索關(guān)鍵詞,擴(kuò)大模糊度搜索更多數(shù)據(jù),其中會匹配單字情況

5.2 代碼說明

  1. 數(shù)據(jù)結(jié)構(gòu): 包含 id、title、description、category、tags
  2. 動態(tài)閾值: 通過滑塊實時調(diào)整模糊度
  3. 高亮顯示: 使用 Fuse.js 返回的 matches 信息進(jìn)行關(guān)鍵詞高亮
  4. 實時搜索: 監(jiān)聽 threshold 變化,自動重新初始化 Fuse

6. 高級用法

6.1 嵌套對象搜索

const data = [
  {
    id: 1,
    name: '公司名稱',
    location: {
      city: '北京',
      address: '朝陽區(qū)'
    },
    tags: ['科技', 'AI']
  }
]

const fuse = new Fuse(data, {
  keys: ['name', 'location.city', 'location.address', 'tags']
})

6.2 數(shù)組字段搜索

const data = [
  { title: '文章1', tags: ['vue', 'javascript'] }
]

const fuse = new Fuse(data, {
  keys: ['tags']  // 自動搜索數(shù)組中的每個元素
})

6.3 自定義匹配函數(shù)

const options = {
  getFn: (obj, key) => {
    // 自定義獲取值的邏輯
    return obj[key]
  }
}

6.4 擴(kuò)展搜索模式

const options = {
  useExtendedSearch: true
}

const fuse = new Fuse(data, options)

// 搜索語法
fuse.search('\'exact phrase')  // 精確短語
fuse.search('!exclude')        // 排除
fuse.search('term1|term2')     // 或

7. 性能優(yōu)化建議

7.1 大數(shù)據(jù)集優(yōu)化

// 對于大數(shù)據(jù)集,預(yù)先創(chuàng)建索引
const fuse = new Fuse(largeData, {
  threshold: 0.3,
  includeMatches: true
})

// 復(fù)用實例,避免重復(fù)創(chuàng)建

7.2 搜索時機(jī)控制

// 防抖搜索
let timer = null
watch(searchQuery, (newVal) => {
  clearTimeout(timer)
  timer = setTimeout(() => {
    results.value = fuse.search(newVal)
  }, 300)
})

7.3 限制返回結(jié)果

const results = fuse.search(query)
const limited = results.slice(0, 10)  // 只取前10條

8. 常見問題

Q1: 如何處理中文搜索?

A: Fuse.js 默認(rèn)支持中文,無需特殊配置。

Q2: 搜索速度慢怎么辦?

A:

  1. 減少 keys 數(shù)量
  2. 提高 threshold 值
  3. 限制數(shù)據(jù)集大小
  4. 使用防抖避免頻繁搜索

Q3: 如何實現(xiàn)多關(guān)鍵詞搜索?

A:

const query = 'vue javascript'
const results = fuse.search(query)

Q4: 如何清除搜索結(jié)果?

A:

if (!query.trim()) return []

9. 完整參數(shù)速查表

參數(shù)類型默認(rèn)值說明
keysstring[][]搜索字段
thresholdnumber0.6模糊度 (0-1)
includeScorebooleanfalse包含分?jǐn)?shù)
includeMatchesbooleanfalse包含匹配信息
minMatchCharLengthnumber1最小匹配字符
shouldSortbooleantrue結(jié)果排序
ignoreLocationbooleanfalse忽略位置
findAllMatchesbooleanfalse查找所有匹配
useExtendedSearchbooleanfalse擴(kuò)展搜索模式
locationnumber0匹配位置權(quán)重
distancenumber100匹配距離
maxPatternLengthnumber32最大模式長度

10. 總結(jié)

Fuse.js 是一個功能強(qiáng)大且易用的模糊搜索庫,適用于:

  • ? 搜索框?qū)崟r搜索
  • ? 大屏列表篩選
  • ? 離線文檔搜索
  • ? 系統(tǒng)菜單導(dǎo)航
  • ? 知識庫檢索

通過合理配置參數(shù),可以實現(xiàn)從精確到模糊的各種搜索需求,并提供良好的用戶體驗。

相關(guān)資源

到此這篇關(guān)于Fuse.js前端模糊搜索神器從入門到精通教程的文章就介紹到這了,更多相關(guān)Fuse.js前端模糊搜索內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

马鞍山市| 图们市| 铜陵市| 十堰市| 尉犁县| 武胜县| 宁化县| 宁德市| 石河子市| 凤城市| 十堰市| 陇川县| 惠水县| 高安市| 岳普湖县| 青海省| 邹平县| 古交市| 双峰县| 白水县| 伊春市| 定陶县| 忻城县| 留坝县| 页游| 广昌县| 大关县| 尚义县| 鸡东县| 聂拉木县| 西盟| 顺昌县| 平陆县| 苗栗县| 泰宁县| 冀州市| 大宁县| 长阳| 南华县| 河间市| 横峰县|