Reka UI - 一款免费开源的 Vue 无头 UI 组件库,样式定制开发项目的绝佳选择

近日了解到一款很适合用于定制开发项目的 Vue UI 库,体验了一下很不错,推荐给大家。

作为一名前端开发者,我一直关注着前端组件库的发展。建立「那些免费的砖」这个网站几年间,我陆续介绍过很多国内 Element / TDesign / AntDesign 以及国外 PrimeVue  / Quasar 这样的 Vue 组件库。最近我发现一个在 Vue 生态中崭露头角的新选择 —— Reka UI。早些时候我看到 Reka 这个名字,还以为是 React 生态的 UI 库,最近才发现这套 UI 库还被 Vue 官方推荐了,花时间上手体验了一下。

关于Reka UI

Reka UI 是一个基于 Vue 打造的无头 UI 组件库,主打可访问性开发者友好的设计理念,和国内几个大厂出品的前端组件库不一样,在技术实现和开发体验上的创新还是值得我们关注。

Reka UI 官网
Reka UI 官网

值得说一下,Reka UI 的前身就是 Radix Vue,最近,Nuxt UI v3 在升级版本时,将底层原子组件库从 headless-vue 替换成了 Reka UI,这些都说明 Reka UI 技术底子很强。

技术特性

完全样式控制

与 Element / PrimeVue  / Quasar 这些传统的带有预设样式的组件库不同,Reka UI 作为无头组件库,不提供任何预设样式,而是将样式的完全控制权交还给开发者,比如:

<template>
  <AccordionRoot>
    <AccordionItem
      class="data-[state=open]:border-b-2 data-[state=open]:border-gray-800"
      value="item-1"
    />
  </AccordionRoot>
</template>

<style>
.AccordionItem[data-state="open"] {
  border-bottom-width: 2px;
}
</style>

从上面这段代码可以看出,Reka UI 将组件状态绑定到 HTML 元素的 dataset 中,而不是使用 is- 这种前缀类名,这让我们可以借助 CSS 属性选择器或像 Tailwind CSS 的变体选择器来根据状态应用样式,有更大的灵活性。

强大的动画支持

Reka UI 对动画有着特殊的优化:

.DialogOverlay[data-state="closed"],
.DialogContent[data-state="closed"] {
  animation: fadeOut 300ms ease-in;
}

不直接通过 v-if 控制组件挂载,而是使用一个高阶组件内部状态机,结合节点的创建销毁、动画开始结束等事件来控制实际组件的挂载。这意味着组件可以在动画或缓动效果结束后再销毁节点,从而实现更流畅的用户体验。

Reka UI 部分组件预览
Reka UI 部分组件预览

创新的asChild模式

在前端常见的视图层开发中,由于组件和 DOM 不是一一对应的关系,经常会遇到一个 DOM 节点需要同时作为多个原子组件的情况。Reka UI 通过继承自 Radix 的 asChild模式 来解决了这个问题,比如:

<template>
  <DialogRoot>
    <TooltipRoot>
      <TooltipTrigger asChild>
        <DialogTrigger asChild>
          <ElButton>打开弹框</ElButton>
        </DialogTrigger>
      </TooltipTrigger>
    </TooltipRoot>
    Your Dialog Content
  </DialogRoot>
</template>

通过给组件传递 asChild 属性,可以将其”隐形化”,在去除多余 DOM 结构的同时保留样式和事件等特性,有效解决了组件嵌套过深的问题。

命名空间导入

Reka UI 提供了命名空间式的组件调用方式,可以让代码组织更加清晰:

<template>
  <Dialog.Root>
    <Dialog.Trigger>
      这里写操作按钮组件
    </Dialog.Trigger>
  </Dialog.Root>
  <Dialog.Portal>
    <Dialog.Overlay />
    <Dialog.Content>
      这里写弹框内包含的内容
    </Dialog.Content>
  </Dialog.Portal>
</template>

<script setup lang="ts">
import { Dialog } from 'reka-ui/namespaced'
</script>

这种方式不仅提高了代码的可读性,还有利于摇树优化,因为相关组件被组织在一起按需导入。

开发上手体验

安装与使用

和大多数 Vue 组件库一样,Reka UI 的安装和使用非常简单和直接:

npm install reka-ui

在 Vue 页面中使用:

<template>
  <Dialog.Root>
    <Dialog.Trigger as-child>
      <button>打开对话框</button>
    </Dialog.Trigger>
    <Dialog.Portal>
      <Dialog.Overlay />
      <Dialog.Content>
        <Dialog.Title>操作提示</Dialog.Title>
        <Dialog.Description>确定要删除这条记录吗?</Dialog.Description>
        <Dialog.Close>关闭</Dialog.Close>
      </Dialog.Content>
    </Dialog.Portal>
  </Dialog.Root>
</template>

<script setup lang="ts">
import { Dialog } from 'reka-ui'
</script>

受控与非受控模式

Reka UI 还优雅地处理了受控和非受控组件的问题。在 Vue 生态中,通常通过判断是否传入了model-value来处理。对于非受控组件,Reka UI 推荐使用 default-value 而不是 model-value,这样更符合语义化规范。

Reka UI 开发文档
Reka UI 开发文档

样式自定义实践

一般企业自己封装 UI 库会基于带设计规范的组件库,比如 Ant Design、Element UI 等。二次封装经常会碰到样式冲突问题。

而由于 Reka UI 是无头组件,和那些开箱即用的组件不同,只有最基本的 UI 样式,一般我们需要给组件写样式:

<template>
  <PopoverRoot>
    <PopoverTrigger class="popover-trigger">
      了解更多
    </PopoverTrigger>
    <PopoverPortal>
      <PopoverContent class="popover-content">
        温馨提示:按「Shift + K」可激活快速搜索功能
        <PopoverClose />
        <PopoverArrow class="popover-arrow" />
      </PopoverContent>
    </PopoverPortal>
  </PopoverRoot>
</template>

<style>
.popover-trigger {
  background-color: white;
  border-radius: 3px;
}

.popover-content {
  border-radius: 3px;
  padding: 20px;
  width: 260px;
  background-color: white;
}

.popover-arrow {
  background-color: white;
}
</style>

与其它组件库的对比

与传统组件库的比较

与 TDesign、Element Plus 等传统组件库相比,Reka UI有着根本性的不同:

对比项传统组件库Reka UI
样式控制预设设计系统,有限定制完全控制,无预设样式
设计理念提供完整解决方案提供基础构建块
使用场景快速开发企业级应用需要完全自定义设计系统的项目
学习曲线较低较高,需要精通 CSS
Reka UI 与传统组件库特性对比表

适合的使用场景

设计系统开发

如果我们需要为公司构建统一的设计系统,Reka UI 是绝佳的基础选择,无头特性让我们完全控制组样式和行为,确保与品牌视觉完全一致。

高度定制化的项目

对于需要独特视觉表现的项目,如创意网站、品牌宣传页面等,Reka UI 提供了必要的交互逻辑和可访问性支持,同时允许你实现完全自定义的设计。

总的来说,如果我们在开发对视觉表现有高度定制化需求的项目,使用其他组件库需要写一堆 ::v-deep>>> 来解决样式冲突问题,这时候可以考虑用 Reka UI 来实现了。

需要注意,Reka UI 学习曲线稍高,不少 UI 库选择它作为底层组件库,一旦掌握,会为开发者带来前所未有的灵活性和控制力。

免费开源说明

Reka UI 一个 Vue 生态的 UI 组件库,和 Vue 一样也是一个免费开源的项目,基于 MIT 开源协议开放源码,我们可以免费下载来使用,用在商业项目上也完全没问题。