百度360必应搜狗淘宝本站头条
当前位置:网站首页 > SEO教程 > 正文

搜索组件优化 - Command ?K 搜索框组件

gaoyangw 2024-11-01 12:16 35 浏览 0 评论

前言:

DevNow 项目中我们使用了 DocSearch 来实现搜索功能,但是由于有以下的限制:

  1. 您的网站必须是技术文档或技术博客。
  2. 您必须是网站的所有者,或者至少具有更新其内容的权限
  3. 您的网站必须公开可用
  4. 您的网站必须已准备好生产环境。

由于这些条件的限制, DocSearch 只适合用在开源的技术文档或技术博客中,所以从 DevNow 开源博客项目的定位来说,还是比较适适合的。为什么突然想着要优化一下搜索组件呢?

今天心血来潮想在 blog 上找一篇文章,用搜素的功能发现搜不出来,搜索挂了?然后突然想起来之前由于想着在 blog 中可能加一些私有的配置或者尝鲜的功能,所有 fork 了一份变成 私有项目了,这样就不符合 DocSearch 的 网站必须是公开的这个限制了。

其实用下来我个人感觉还有以下几点不是很满意的地方:

  1. 配置麻烦,需要在 Algolia 上注册账号,然后创建一个应用,然后在项目里配置一些 api-key 信息。
  2. 搜索信息索引的配置可能需要自己在平台上定制化一些 config ,开始可能会比较迷茫。
  3. 索引可能会不及时,默认一周会重新索引一次,所以刚发布的文章可能无法被搜索到。

所以一怒之下就想着改一下,之前想着看看其他的方案,之前在在 shadcn/ui 中看到了一个 Command + K 的搜索组件,所以就想着能不能在 DevNow 中也实现一下。这个实现的方案是基于 cmdk 这个库来实现的, Nextjs 官网应该也是这个实现方案。

cmdk

集成 shadcn/ui

在这里还是推荐使用 shadcn/ui 来集成,因为它提供了很多的组件,而且还提供了一些 hooks 来帮助我们实现一些功能。想着后续可能还会用到一些组件,所以就直接集成了,不得不说这个UI库的样式真是深得我心啊。

安装的话直接跟着 文档 来就好,提供了一些常见框架的集成:

文档

:::tip[注意] 在安装前要先在 tsconfig.json 中配置好 resolve paths @/* 这个是必须有的,否则 shadcn/ui 无法初始化成功

{
  "compilerOptions": {
    // ...
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"] // <--- 这个必须有
    }
    // ...
  }
}

:::

安装 Command

文档在 这里

pnpm dlx shadcn@latest add command

一个简单的例子





const Search: FC<Props> = ({ category }) => {
  const [open, setOpen] = useState(false);
  useEffect(() => {
    const down = (e: KeyboardEvent) => {
      if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
        e.preventDefault();
        setOpen((open) => !open);
      }
    };


    document.addEventListener('keydown', down);
    return () => document.removeEventListener('keydown', down);
  }, []);


  return (
    <div className='mr-4 hidden items-center lg:flex'>
      <Button
        onClick={() => setOpen((open) => !open)}
        size='sm'
        className='h-[32px] bg-muted/50 px-2 py-0 text-sm text-muted-foreground shadow-none hover:bg-accent focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring'
      >
        Search
        <kbd className='pointer-events-none ml-1 inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100'>
          <span className='text-xs'>?</span>K
        </kbd>
      </Button>


      {config.search && (
        <CommandDialog open={open} onOpenChange={setOpen}>
          <CommandInput placeholder='Type a command or search...' />
          <CommandList>
            <CommandEmpty>No results found.</CommandEmpty>
            {category.map((item, index) => (
              <Fragment key={index}>
                <CommandGroup heading={item.label}>
                  {item.children.map((child, cIndex) => (
                    <CommandItem
                      // 这里需要注意的是:
                      // 选项点击选中的事件是 onSelect 不是 onClick
                      onSelect={() => {
                        window.open(`${location.origin}/posts/${child.id}`, '_blank');
                      }}
                      key={cIndex}
                      className='cursor-pointer'
                    >
                      <span>{child.label}</span>
                    </CommandItem>
                  ))}
                </CommandGroup>
                {index === category.length - 1 && <CommandSeparator />}
              </Fragment>
            ))}
          </CommandList>
        </CommandDialog>
      )}
    </div>
  );
};

效果展示:

使用 DocSearch

DocSearch

使用 command 替换后:

command

大家觉得哪个更好呢,我个人觉得新版的会更加简洁一点。

遇到的问题

第一版的实现到这里就结束了,然后上线后发现了问题。发现线上的环境突然变卡了,请求也变多了,一看发现堵了很多请求:

文件请求问题

然后就是定位问题,发现原因是: 当我在 Astro 中集成 React 框架时,如果组件是运行要求在客户端运行时:

<Search client:only='react' />

在通过 client:only 来标记的组件中获取所有文件的标题时,会把所有的请求一遍,这里我的理解是在客户端没有这些信息,所有执行的时候会构建一份。

这里如果改下数据源,将数据传递给 Search的话,可以规避掉这个问题。

<Search category={category}  client:only='react'>


原文链接:搜索组件优化 - Command ?K | DevNow

相关推荐

Chrome43正式版发布 新增海量应用扩展

2015-07-0809:26:10作者:刘菲菲谷歌Chrome浏览器一向被大家称为“版本帝”,原因就是更新频率相当高。最近,Chrome又发布了新版,版本号为v43.0.2357.132。本次更...

软网推荐:快速下载需要的谷歌浏览器扩展

谷歌浏览器现在已经不是一个单纯的网页浏览器,而更加像是一个管理操作平台,因为它的很多功能都是通过功能扩展来实现的。但是通常我们要想访问谷歌的扩展商店非常的麻烦,所以就需要寻求其他的解决方法。第三方扩展...

谷歌预告3项Chrome浏览器改进,提高管理标签页效率

IT之家9月11日消息,谷歌公司昨日(9月10日)发布新闻稿,宣布为iOS和安卓版Chrome浏览器引入3项改进,从而帮助用户提高管理标签页效率。1.在iOS上体验标签页...

谷歌发布Chrome浏览器更新,修复密码消失问题:持续18个小时

IT之家7月27日消息,谷歌发布Chrome浏览器更新,修复了存在于密码管理器中的错误,该错误导致Chrome用户密码消失18个小时。Chrome用户反馈更新到版本127.0....

谷歌浏览器Chrome 38.0.2125.101稳定版下载

IT之家(www.ithome.com):谷歌浏览器Chrome38.0.2125.101稳定版下载今天,谷歌浏览器团队带来最新版Chrome稳定版更新。具体版本号为38.0.2125.101,该版...

谷歌浏览器8年后首换新LOGO,变了又好像没变

近日,ChromeCanary版浏览器(开发者专用的每日构建版)在新版中首次更新了浏览器图标,意味着这个新的图标很快将开始出现在各位用户的设备上了。...

谷歌浏览器,居然被山寨了(谷歌浏览器可靠吗)

大家看看下面两张Logo,光看图标你能分辨出来哪个是假的Chrome,哪个是真的吗?...

谷歌浏览器Chrome 45.0.2454.93稳定版下载

IT之家讯谷歌Chrome浏览器更新至45.0.2454.93稳定版。谷歌官方并没有给出更新日志,因此本次更新重点在于小范围问题修复。Chrome浏览器用户可下载并且更新至该版本。Chrome45...

微软推出的新版Edge浏览器,让我抛弃用了5年的谷歌

随着新版Edge浏览器的发布,这个微软的亲儿子以崭新的面貌和大家见面啦。这次更新可谓是好评如潮,相比浏览器届的老大哥——谷歌浏览器,它少了些臃肿,但又多了一些独特的功能。今天,我就为大家介绍8...

谷歌Chrome浏览器安卓版将支持Material You设计版地址栏

IT之家1月26日消息,Google的MaterialYou主题在Android上提供了一致的配色方案。谷歌现在正在为Android上的谷歌Chrome浏览器的地址栏提供...

你想要的功能,Edge浏览器都有(你想要的功能,edge浏览器都有哪些)

2020年之前,如果有求推荐一款好用的浏览器,那谷歌Chrome浏览器一定是最好的选择,现在却不一定了。今年一月份,微软正式推出了基于谷歌Chromium内核的MicrosoftEdge浏览器,它继...

谷歌浏览器Chrome更新:图标再变动,版号来到100

经过十多年的更新,谷歌浏览器GoogleChrome终于迎来了“100”的版本号,并在近日于Windows、Mac、iOS和安卓等多个平台正式上线。尽管是很有象征性意义的版本号更新,但它这一...

不再桌面端独占,谷歌Chrome浏览器安卓版将迎来任务管理器

IT之家10月4日消息,谷歌Chrome浏览器即将为Android用户带来一项备受期待的功能——任务管理器。虽然Chrome浏览器在桌面端已经具备了任务管理器的功能,但移动端一...

安卓版谷歌Chrome浏览器测试新面板,方便用户管理跨设备标签页

IT之家8月30日消息,科技媒体mspoweruser昨日(8月29日)发布博文,报道称Canary频道最新安卓版谷歌Chrome浏览器正测试新特性,为跨设备标签页添加了一个...

谷歌浏览器,网站页面禁用右键功能,如何解决?

进入浏览器开发者工具点击谷歌浏览器右上角三个点,选择【更多工具】——【开发者工具】找到“代码段”【源代码/来源】——【>>】——【代码段】...

取消回复欢迎 发表评论: