意见箱
恒创运营部门将仔细参阅您的意见和建议,必要时将通过预留邮箱与您保持联络。感谢您的支持!
意见/建议
提交建议

前端 - 撸了一款 Vue 生态缺失的 CMD+K 类库_个人文章

来源:恒创科技 编辑:恒创科技编辑部
2022-10-01 10:57:04

9月底,新轮子又来了,Vue Command Palette 是一个为 Vue 而生的快速、无样式、可组合的 Command Palette(CMDK)组件库。

灵感来源

这个组件的诞生的灵感来自上个月观察到一个比较火的 React 类库项目 cmdk


前端 - 撸了一款 Vue 生态缺失的 CMD+K 类库_个人文章

cmdk 是一个为 React 而生的快速、无样式、可组合的 CMDK 组件,由 Linear 工程师 Paco Coursey 和他的设计师小伙伴合力开发的,一周内获得 3k Star。

其特点是无样式的,只提供基础的功能框架,可组合的组件 API,便于扩展,这样一来,你可以基于它二次开发,编写成任何你想要的样子。

官网也做的比较用心,编写了四种样式作为例子,有 RaycastLinearVercelFramer

发现 Vue 生态内缺少一款好用的 CMDK 类库,于是决定自己造一个(chaoxi)。

如果你还不知道什么是 CMDK,这里简单介绍下。

CMDK 是一种用户体验

CMDK 是 CMD + K 的缩写,CMD 代表 Mac 系统中的键位 ⌘ ,对应 Command。CMD + K 是组合键,需要同时按下或者先后按下。

其实 CMDK 这种用户体验我们或多或少都接触过,Mac 自带的 聚焦搜索 就是这样的一个工具 ⌘ + Space 即可唤起它进行搜索,或者作为开发者查阅一些文档的时候,都会带有搜索的功能,有时候会发现都是嵌入的 algolia search, 再或者在使用 VSCode 的时候打开的命令面板(⇧ + ⌘ + P)

在去年发现 Raycast 这个 App 之后,生产力明显上升,Raycast 可以自定义很多快捷方式,可以结合一些工具打造顺滑的工作流,比如 Raycast 结合 GitHub 去 Create Issue,结合 Linear 去 Create Issue 等等。

所以我认为一个好的工具类、文档类的站点,应当内置一个好用的 CMDK 功能,可以大幅提升效率,以下工具都是一些实现比较好的代表。

VercelGitHubRaycastLinearFramerAlgolia

你不妨也去试试,没准儿在哪个你正在访问的网站悄悄的支持着 CMDK,你敲一下 ⌘ + K 就能唤起呢。

Vue 中的命名空间组件

这次的组件设计有别于以往的组件开发方式,使用了 Vue 中的命名空间组件 的编写方式,在了解命名空间组件之前,我们先了解一下复合组件

复合组件

cmdk 类库提到了它的组件设计借鉴了《React Hooks: Compound Components》这篇文章中提到的 React 中的 复合组件 设计模式。

那什么是 复合组件 呢,它是一种组件的设计模式,一般适用于有两个或者多个组件一起工作,通常一个组件是父组件、而其他的是子组件。

我们在使用的大部分 UI 类库都会采用复合组件的设计模式去编写复杂组件,比如我们常用的 SelectMenuTable 等等组件到实现方式都是复合组件。

令我好奇的是 cmdk 这个 React 类库中采用的是 <父组件.子组件 /> 的引入方式,例如 cmdk 官网的例子:

import { Command } from 'cmdk';

<Command.Dialog open={open} onOpenChange={setOpen}>
  <Command.Input />

  <Command.List>
    {loading && <Command.Loading>Hang on…</Command.Loading>}

    <Command.Empty>No results found.</Command.Empty>

    <Command.Group heading="Fruits">
      <Command.Item>Apple</Command.Item>
      <Command.Item>Orange</Command.Item>
      <Command.Separator />
      <Command.Item>Pear</Command.Item>
      <Command.Item>Blueberry</Command.Item>
    </Command.Group>

    <Command.Item>Fish</Command.Item>
  </Command.List>
</Command.Dialog>

上面代码中出现的 <Command.Dialog><Command.List> 等组件引入方式,是在 Vue 中很少采用的方式,我在想为什么不可以呢,于是想去试试。

原生 HTML

举个例子:

例如 HTML 中的 <select><option> 标签:

<select>
  <option value="value1">key1</option>
  <option value="value2">key2</option>
  <option value="value3">key3</option>
</select>
常规组件

通常在 Vue 中实现,我们需要编写两个组件,假设是 MySelect 作为父级组件,MyOption 作为子组件

<template>
  <fieldset>
    <legend>currentValue: {{selected}}</legend>
    <MySelect v-model="selected">
      <MyOption :value="1">One</MyOption>
      <MyOption :value="2">Two</MyOption>
      <MyOption :value="3">Three</MyOption>
    </MySelect>
  </fieldset>
</template>

<script setup>
import { ref } from 'vue'
import MySelect from './MySelect.vue'
import MyOption from './MyOption.vue'

const selected = ref('1')
</script>
上一篇: 租用美国服务器:潜在的风险与应对策略。 下一篇: MongoDB 5.0 扩展开源文档数据库操作