VuePress 生态系统VuePress 生态系统
  • 主题指南
  • 默认主题
  • Hope 主题
  • Plume 主题
  • Reco 主题
  • 功能插件
  • Markdown 插件
  • 搜索插件
  • 博客插件
  • 渐进式应用插件
  • 统计分析插件
  • 搜索引擎优化插件
  • 开发插件
  • 工具插件
  • AI 插件
  • @vuepress/helper
  • English
  • 简体中文
GitHub
  • 主题指南
  • 默认主题
  • Hope 主题
  • Plume 主题
  • Reco 主题
  • 功能插件
  • Markdown 插件
  • 搜索插件
  • 博客插件
  • 渐进式应用插件
  • 统计分析插件
  • 搜索引擎优化插件
  • 开发插件
  • 工具插件
  • AI 插件
  • @vuepress/helper
  • English
  • 简体中文
GitHub
  • 搜索插件指南
  • docsearch
  • meilisearch
  • search
  • slimsearch

slimsearch

@vuepress/plugin-slimsearch

一个强大的客户端搜索插件,支持自定义索引和全文搜索。

使用方法

npm i -D @vuepress/plugin-slimsearch@next
.vuepress/config.ts
import { slimsearchPlugin } from '@vuepress/plugin-slimsearch'

export default {
  plugins: [
    slimsearchPlugin({
      // 选项
    }),
  ],
}

搜索索引

基于 slimsearch,该插件能够提供超快的搜索体验,即使在大型站点上也是如此。

默认情况下,插件只会索引标题、文章摘要以及你配置的自定义字段。如果你希望索引页面的全部内容,需要在插件选项中设置 indexContent: true。

如果要防止某个页面被索引,可以在其 Frontmatter 中设置 search: false。如果需要通过编程方式过滤页面(例如根据路径排除),可以使用 filter 选项。

自定义字段

无论你是主题开发者还是普通用户,通过 Frontmatter 或 extendsPage 生命周期为页面添加额外数据是很常见的,在大多数情况下,你可能也希望索引这些数据。

customFields 选项接受一个数组,每个元素代表一个自定义搜索索引配置项。每个配置项包含两个部分:

  • getter: 该自定义字段的获取器。这个函数接收 page 对象作为参数,并返回需要被索引的值(可以是字符串、字符串数组,或者在缺失时返回 null/undefined)。
  • formatter: 控制该条目在搜索结果中如何显示的格式字符串或对象。其中 $content 会被替换为 getter 返回的实际值。如果你的站点支持多语言,也可以将其设置为对象,以便为每种语言单独设置显示格式。

这些数据将被添加到索引中,并包含在搜索结果里。

示例:将作者添加到索引

假设你在 Frontmatter 中通过 author 字段添加了作者信息:

---
author: 你的名字
---

你的 Markdown 内容...

你可以通过如下设置将作者信息添加到索引中:

.vuepress/config.ts
import { slimsearchPlugin } from '@vuepress/plugin-slimsearch'

export default {
  plugins: [
    slimsearchPlugin({
      customFields: [
        {
          name: 'author',
          getter: (page) => page.frontmatter.author,
          formatter: '作者: $content',
        },
      ],
    }),
  ],
}

示例:添加更新时间

假设你正在使用 @vuepress/plugin-git 插件,并且将中文和英文文档分别放置在 /zh/ 和 / 目录下。

你可以通过以下设置来索引更新时间:

.vuepress/config.ts
import { slimsearchPlugin } from '@vuepress/plugin-slimsearch'
import { defineUserConfig } from 'vuepress'

export default defineUserConfig({
  // 假设你使用如下多语言配置
  locales: {
    '/': {
      lang: 'en-US',
    },
    '/zh/': {
      lang: 'zh-CN',
    },
  },

  plugins: [
    slimsearchPlugin({
      customFields: [
        {
          name: 'updateTime',
          getter: (page) => page.data.git?.updateTime.toLocaleString(),
          formatter: {
            '/': 'Update time: $content',
            '/zh/': '更新时间:$content',
          },
        },
      ],
    }),
  ],
})

选项

indexContent

  • 类型: boolean
  • 默认值: false

是否启用内容索引。

提示

默认情况下,只会索引页面的标题、摘要以及你的自定义字段。如果需要索引页面的正文内容,请将此选项设置为 true。

suggestion

  • 类型: boolean
  • 默认值: true

是否在搜索时显示建议。

customFields

  • 类型: CustomFieldOptions[]

    interface CustomFieldOptions {
      /**
       * 自定义字段获取器
       */
      getter: (page: Page) => string[] | string | null | undefined
    
      /**
       * 展示内容
       *
       * @description `$content` 会被 `getter` 返回的内容替换
       *
       * @default `$content`
       */
      formatter?: Record<string, string> | string
    }

自定义索引字段配置。

hotKeys

  • 类型: (KeyOptions | string)[]

    export interface KeyOptions {
      /**
       * Value of `event.key` to trigger the hot key
       *
       * 热键的 `event.key` 值
       */
      key: string
    
      /**
       * Whether to press `event.altKey` at the same time
       *
       * 是否同时按下 `event.altKey`
       *
       * @default false
       */
      alt?: boolean
    
      /**
       * Whether to press `event.ctrlKey` at the same time
       *
       * 是否同时按下 `event.ctrlKey`
       *
       * @default false
       */
      ctrl?: boolean
    
      /**
       * Whether to press `event.shiftKey` at the same time
       *
       * 是否同时按下 `event.shiftKey`
       *
       * @default false
       */
      shift?: boolean
    
      /**
       * Whether to press `event.metaKey` at the same time
       *
       * 是否同时按下 `event.metaKey`
       *
       * @default false
       */
      meta?: boolean
    }
  • 默认值: [{ key: "k", ctrl: true }, { key: "/", ctrl: true }]

指定热键的 event.key。

当按下热键时,搜索框输入框将获得焦点。设置为空数组以禁用热键。

queryHistoryCount

  • 类型: number
  • 默认值: 5

最大存储的搜索查询历史记录数量,设置为 0 以禁用。

resultHistoryCount

  • 类型: number
  • 默认值: 5

最大存储的匹配结果历史记录数量,设置为 0 以禁用。

searchDelay

  • 类型: number
  • 默认值: 150

输入后开始搜索的延迟时间(毫秒)。

注

在内容庞大的站点上进行客户端搜索可能会较慢,在这种情况下,你可能需要增加此值,以确保用户在搜索开始前已完成输入。

filter

  • 类型: (page: Page) => boolean
  • 默认值: () => true

用于过滤页面的函数。

sortStrategy

  • 类型: "max" | "total"
  • 默认值: "max"

结果排序策略。

当有多个匹配结果时,结果将按此策略排序。max 表示具有更高最大分数的页面将排在前面。total 表示具有更高总分数的页面将排在前面。

worker

  • 类型: string
  • 默认值: slimsearch.worker.js

输出 Worker 的文件名。

hotReload

  • 类型: boolean
  • 默认值: 是否启用了 --debug 标志

是否在开发服务器中启用热重载。

注

默认情况下它是禁用的,因为对于内容庞大的站点,此功能会对性能产生巨大影响,并在编辑 Markdown 时显著降低热重载速度。

indexOptions

  • 类型: SlimSearchIndexOptions

    interface SlimSearchIndexOptions {
      /**
       * 用于对索引字段项进行分词的函数。
       */
      tokenize?: (text: string, fieldName?: string) => string[]
      /**
       * 用于处理或标准化索引字段中词条的函数。
       */
      processTerm?: (term: string) => string[] | string | false | null | undefined
    }

用于创建索引的选项。

indexLocaleOptions

  • 类型: Record<string, SlimSearchIndexOptions>

每个语言环境用于创建索引的选项,对象键应为语言环境路径。

locales

  • 类型: SlimSearchLocaleConfig

    interface SlimSearchLocaleData {
      /**
       * 搜索框占位符
       */
      placeholder: string
    
      /**
       * 搜索文字
       */
      search: string
    
      /**
       * 清空搜索文字
       */
      clear: string
    
      /**
       * 移除当前条目
       */
      remove: string
    
      /**
       * 搜索中文字
       */
      searching: string
    
      /**
       * 取消文字
       */
      cancel: string
    
      /**
       * 默认标题
       */
      defaultTitle: string
    
      /**
       * 选择提示
       */
      select: string
    
      /**
       * 切换提示
       */
      navigate: string
    
      /**
       * 自动补全提示
       */
      autocomplete: string
    
      /**
       * 关闭提示
       */
      exit: string
    
      /**
       * 加载提示
       */
      loading: string
    
      /**
       * 搜索查询历史标题
       */
      queryHistory: string
    
      /**
       * 搜索结果历史标题
       */
      resultHistory: string
    
      /**
       * 搜索历史为空提示
       */
      emptyHistory: string
    
      /**
       * 结果为空提示
       */
      emptyResult: string
    }
    
    interface SlimSearchLocaleConfig {
      [localePath: string]: SlimSearchLocaleData
    }

搜索插件的多语言配置。

内置支持的语言
  • 简体中文 (zh-CN)
  • 繁体中文 (zh-TW)
  • 英语 (美国) (en-US)
  • 德语 (de-DE)
  • 俄语 (ru-RU)
  • 乌克兰语 (uk-UA)
  • 越南语 (vi-VN)
  • 葡萄牙语 (pt)
  • 波兰语 (pl-PL)
  • 法语 (fr-FR)
  • 西班牙语 (es-ES)
  • 斯洛伐克语 (sk-SK)
  • 日语 (ja-JP)
  • 土耳其语 (tr-TR)
  • 韩语 (ko-KR)
  • 芬兰语 (fi-FI)
  • 印尼语 (id-ID)
  • 荷兰语 (nl-NL)

Frontmatter

search

  • 类型: boolean
  • 默认值: true

是否索引该页面。

进阶

自定义索引生成

你可以通过 indexOptions 和 indexLocaleOptions 自定义索引生成过程,以便获得更好的索引结果,并可针对每个语言环境单独设置。

目前我们使用 Intl.Segmenter API 在构建搜索索引时进行分词。这在大多数语言中效果良好,但为了获得更高的准确性,你可能希望通过 tokenize 选项自定义分词过程。

使用 API

如果你想访问搜索 API,你需要从 @vuepress/plugin-slimsearch/client 导入 createSearchWorker 函数:

import { createSearchWorker } from '@vuepress/plugin-slimsearch/client'
import { defineClientConfig } from 'vuepress/client'

const { all, suggest, search, terminate } = createSearchWorker()

// 建议某些内容
suggest('key').then((suggestions) => {
  // 显示搜索建议
})

// 搜索某些内容
search('keyword').then((results) => {
  // 显示搜索结果
})

// 同时返回建议和结果
all('key').then(({ suggestions, results }) => {
  // 显示搜索建议和结果
})

// 不需要时终止 worker
terminate()

开发服务器中的限制

搜索服务由 Worker 提供支持,在开发模式下,我们无法像生产环境那样打包 Worker 文件。

为了在开发模式下加载搜索索引,我们使用了 type: "module" 的现代 Service Worker。因此,如果你想在 DevServer 中尝试搜索,请确保你使用的浏览器支持该特性(查看 CanIUse 了解支持详情)。

为了获得更好的性能,在开发模式下添加/编辑/删除 Markdown 内容默认不会触发搜索索引的更新。如果你正在校对或优化搜索结果,可以通过设置 hotReload: true 选项来启用热重载。

与服务端搜索对比

客户端搜索具有无需后端服务且易于添加等优势,但你也应该了解其缺点。

缺点

  1. 构建时间:你需要在构建阶段索引你的网站,这会增加网站部署时间和打包体积。
  2. 带宽压力:用户在搜索前需要从你的服务器获取完整的搜索索引,这将给你的服务器带来额外的流量和带宽压力。站点内容越多,搜索索引就越大。
  3. 延迟:要执行搜索,用户必须等待搜索索引下载并在本地解析。这可能比通过简单的网络请求从服务端搜索获取结果要慢得多。
  4. 设备性能:由于搜索是在用户设备上完成的,速度完全取决于设备的性能。

在大多数情况下,如果你正在构建一个大型站点,如果条件允许,应该选择服务提供商为你的站点提供搜索服务(如 Algolia),或者选择开源的搜索爬虫工具并将其托管在自己的服务器上,以提供搜索服务并定期爬取你的站点。这对于大型站点是必要的,因为用户通过网络请求将搜索词发送到搜索 API 并直接获取搜索结果。

特别地,DocSearch 是 Algolia 为开源项目提供的免费搜索服务。如果你正在创建开源项目文档或开源技术博客,你可以申请使用,并使用 @vuepress/plugin-docsearch 插件来提供搜索功能。

客户端配置

defineSearchConfig

自定义 搜索选项,接受普通对象、Ref 或 Getter 函数作为参数。

由于搜索是在 Web Worker 中完成的,因此不支持直接为 slimsearch 设置函数类型的选项。

为了提供更准确的搜索查询、建议和结果,我们提供了 querySplitter、suggestionsFilter 和 resultsFilter 选项。你可以为特定语言或所有语言设置它们:

interface SearchLocaleOptions extends Omit<
  SearchOptions,
  'boostDocument' | 'fields' | 'filter' | 'processTerm' | 'tokenize'
> {
  /** 分词函数 */
  querySplitter?: (query: string) => Promise<string[]>

  /** 建议过滤器函数 */
  suggestionsFilter?: (
    suggestions: string[],
    query: string,
    locale: string,
    pageData: PageData,
  ) => string[]

  /** 搜索结果过滤器函数 */
  resultsFilter?: (
    results: SearchResult[],
    query: string,
    locale: string,
    pageData: PageData,
  ) => SearchResult[]
}

interface SearchOptions extends SearchLocaleOptions {
  /** 为每个语言环境设置不同的选项 */
  locales?: Record<string, SearchLocaleOptions>
}

export const defineSearchConfig: (
  options: MaybeRefOrGetter<SearchOptions>,
) => void
.vuepress/client.ts
import { defineSearchConfig } from '@vuepress/plugin-slimsearch/client'

defineSearchConfig({
  // 在此处设置全局搜索选项

  locales: {
    '/zh/': {
      // 为中文设置不同的选项
    },
  },
})

组件

  • SearchBox
在 GitHub 上编辑此页
上次更新: 2025/11/29 07:11
贡献者: Mister-Hope, pengzhanbo
上一页
search