
近日了解到一款很适合用于定制开发项目的 Vue UI 库,体验了一下很不错,推荐给大家。
作为一名前端开发者,我一直关注着前端组件库的发展。建立「那些免费的砖」这个网站几年间,我陆续介绍过很多国内 Element / TDesign / AntDesign 以及国外 PrimeVue / Quasar 这样的 Vue 组件库。最近我发现一个在 Vue 生态中崭露头角的新选择 —— Reka UI。早些时候我看到 Reka 这个名字,还以为是 React 生态的 UI 库,最近才发现这套 UI 库还被 Vue 官方推荐了,花时间上手体验了一下。
关于Reka UI
Reka UI 是一个基于 Vue 打造的无头 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
控制组件挂载,而是使用一个高阶组件内部状态机,结合节点的创建销毁、动画开始结束等事件来控制实际组件的挂载。这意味着组件可以在动画或缓动效果结束后再销毁节点,从而实现更流畅的用户体验。

创新的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
,这样更符合语义化规范。

样式自定义实践
一般企业自己封装 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 提供了必要的交互逻辑和可访问性支持,同时允许你实现完全自定义的设计。
总的来说,如果我们在开发对视觉表现有高度定制化需求的项目,使用其他组件库需要写一堆 ::v-deep
和 >>>
来解决样式冲突问题,这时候可以考虑用 Reka UI 来实现了。
需要注意,Reka UI 学习曲线稍高,不少 UI 库选择它作为底层组件库,一旦掌握,会为开发者带来前所未有的灵活性和控制力。
免费开源说明
Reka UI 一个 Vue 生态的 UI 组件库,和 Vue 一样也是一个免费开源的项目,基于 MIT 开源协议开放源码,我们可以免费下载来使用,用在商业项目上也完全没问题。