Headless组件库:组件开发的新选择

一般来说,在构建UI的时候,每家公司针对UI组件库都有自己定制的需求和样式,那么如何实现呢?

传统的组件库如 Material-UI (MUI) 和 Ant Design (antd) 提供了一整套预先设计好的、风格统一的组件,方便开发者快速构建应用。然而,这类组件库也存在一些缺点,这些缺点正是促使 Headless 组件库概念流行的原因。

传统组件库与 Headless 组件库的对比

特性 传统组件库 (MUI, antd) Headless 组件库
样式控制 难以完全覆盖和定制 完全控制,自定义样式
包体积 较大,包含大量预定义样式和功能 轻量,无预定义样式
设计约束 受组件库设计风格限制 无设计约束,自由定义
CSS 冲突 容易发生,与项目其他样式冲突 几乎不会发生,无样式冲突
可组合性 提供完整组件,组合灵活性相对较低 提供基础功能模块,组合灵活性高
开发效率 提供即用型组件,快速搭建原型和UI 结合 Tailwind CSS 等工具,提升定制开发效率

因此,Headless 组件库的流行是因为它们解决了传统组件库在样式定制、包体积、设计约束和 CSS 冲突方面的缺点。它们提供了更高的灵活性和可组合性,使开发者能够根据项目需求构建高度定制化的用户界面,同时提升开发效率和代码维护性。总之,Headless UI 标志着 Web 开发的重大转变,为开发人员在设计用户界面方面提供了无与伦比的控制和灵活性。

需要说明的是,甚至像 MUI(Material UI)Mantine 这样传统的组件库也开始意识到无头 UI 的重要性,并且提供无头UI 解决方案。

MUI Headless支持:https://mui.com/base-ui/getting-started/

Mantine Headless支持 https://mantine.dev/styles/unstyled/

主流Headless组件库介绍

Radix UI

Radix UI 是一个开源的无头 UI 组件库,用于构建设计系统、网站和 Web 应用程序。它由 Modulz 团队创建,并于 2020 年 11 月推出。Radix UI 是一个 React 组件库。然而,社区中的创作者已经开发了 Vue 和 Svelte 版本。

作为一个无头 UI 库意味着 Radix UI 不附带任何样式。相反,我们可以使用我们首选的样式解决方案来设置无头 UI 组件的样式,以满足我们的品牌和网站要求。Tailwind CSS 是 Radix 组件的常用样式选项。

许多开发人员使用 Radix UI,因为它简化了开发和维护。Radix UI 在前端空间中也被广泛采用,因为它提供了完全可访问的优惠。其组件已在各种浏览器和辅助技术上进行了严格测试,以确保完全符合 WAI-ARIA 可访问性指南。

主要特点

  • Unstyled Components: 提供无样式的基础组件,允许开发者完全控制样式。
  • Accessibility: 强调无障碍访问,确保组件对所有用户友好。
  • Composable: 组件高度可组合,允许开发者组合基础组件来创建复杂的 UI 元素。
  • Framework Support: 主要支持 React,但目前在社区中,已经支持Vue和Svelte。

Headless UI:

Headless UI 是一个由 Tailwind Labs 开发的无样式组件库,专注于提供完全可访问且高度可定制的 UI 组件。它的设计哲学是与 Tailwind CSS 紧密结合,但并不强制要求使用 Tailwind CSS。Headless UI 目前支持 React 和 Vue 两个框架,提供了与这些框架特性深度集成的组件。

主要特点

  1. 无样式组件: Headless UI 提供的组件没有任何预定义样式,开发者需要自行添加样式。这意味着这些组件不会强制你使用特定的 CSS 样式,可以根据项目需求完全自定义外观。
  2. 与 Tailwind CSS 的紧密配合: 虽然 Headless UI 是无样式的,但它设计之初就考虑到了与 Tailwind CSS 的配合(但并不强制使用 Tailwind CSS)。因此,使用 Headless UI 组件时,开发者往往会发现使用 Tailwind CSS 来为这些组件添加样式非常方便。这种设计使得它在与 Tailwind CSS 一起使用时具有极高的开发效率和一致性。
  3. 框架支持: Headless UI 提供了针对 React 和 Vue 的版本,每个版本都充分利用了对应框架的特性(如 React 的 Hooks 和 Vue 的 Composition API)。

以 Headless UI 为例,下面是如何使用它创建一个简单的对话框组件:

import { Fragment, useState } from 'react';
import { Dialog, Transition } from '@headlessui/react';

function MyDialog() {
const [isOpen, setIsOpen] = useState(false);

return (
<>
<button onclick=“{()” ==“”> setIsOpen(true)}>Open Dialog

  <transition show="{isOpen}" as="{Fragment}">
    <dialog as="div" classname="fixed inset-0 z-10 overflow-y-auto" onclose="{()" ==""> setIsOpen(false)}&gt;
      <div classname="min-h-screen px-4 text-center">
        <dialog.overlay classname="fixed inset-0 bg-black opacity-30">

        <span classname="inline-block h-screen align-middle" aria-hidden="true">​</span>

        <div classname="inline-block w-full max-w-md p-6 my-8 overflow-hidden text-left align-middle transition-all transform bg-white shadow-xl rounded-2xl">
          <dialog.title as="h3" classname="text-lg font-medium leading-6 text-gray-900">
            Payment successful
          </dialog.title>
          <div classname="mt-2">
            <p classname="text-sm text-gray-500">
              Your payment has been successfully submitted. We’ve sent you an email with all of the details of your order.
            </p>
          </div>

          <div classname="mt-4">
            <button type="button" classname="inline-flex justify-center px-4 py-2 text-sm font-medium text-blue-900 bg-blue-100 border border-transparent rounded-md hover:bg-blue-200" onclick="{()" ==""> setIsOpen(false)}&gt;
              Got it, thanks!
            </button>
          </div>
        </div>
      </dialog.overlay></div>
    </dialog>
  </transition>

);
}

export default MyDialog;

Shadcn UI

作为2023 JavaScript Rising Stars 中年度最火的项目, shadcn/ui组件库不得不提。由于默认有比较好看的样式,其实理论上它并不算是无头组件库,这个组件库其实是radix-ui的基础上,高度集成了tailwind.css,但是依然保留了高定制性,因此越来越成为很多前端项目的首选。特别是国外,react+next.js+shadcn+tailwind.css基本上成为很多项目标配。

特点:

  • Tailwind CSS集成: 深度集成 Tailwind CSS,提供带有默认样式的组件,但仍然保持高度可定制性。
  • 主题定制化: 支持定制化主题,允许开发者在使用默认样式的基础上进行主题定制。
  • 实用性优先(Utility-First Approach): 采用 Tailwind CSS 的实用类方法,使得样式定义简洁高效。Utility-First Approach
  • 组件样式预定义: 提供预定义样式的组件,减少开发者的样式设计工作量,但仍然可以根据需要进行修改。

文中提到的组件库总结对比

特性 Radix UI Headless UI Shadcn UI
样式控制 无样式,完全自定义 无样式,通常结合 Tailwind CSS 使用 带有默认样式,深度集成 Tailwind CSS
设计约束 无设计约束,自由定义 无设计约束,自由定义 提供预定义样式,可在此基础上进行定制
框架支持 主要支持 React,社区支持vue 强依赖 React 和 Vue 深度集成 Tailwind CSS,支持 React
可组合性 高度可组合的基础组件 高度可组合的基础组件 提供预定义样式的组件,减少样式设计时间
可访问性 强调无障碍访问 强调无障碍访问 默认注重无障碍访问,依赖 Tailwind CSS 实现
使用场景 需要完全自定义和无障碍访问的项目 使用 Tailwind CSS 并需要框架特性支持的项目 快速构建 UI,使用 Tailwind CSS 并需要定制化

适用场景总结

  • Radix UI:适合需要完全自定义样式和外观,强调无障碍访问和可组合性的项目。
  • Headless UI:适合已经使用 Tailwind CSS 的项目,充分利用框架特性(React/Vue),并需要无样式组件的项目。
  • Shadcn UI:适合希望快速构建 UI,并在预定义样式基础上进行灵活定制,深度集成 Tailwind CSS 的项目。

总结

无头组件库为前端开发者提供了一种更加灵活和高效的方式来构建用户界面。通过完全控制组件的样式和行为,开发者可以更好地满足项目的独特需求,同时确保无障碍访问和良好的用户体验。无论是需要高度定制化的企业应用,还是快速迭代的前端项目,无头组件库都能为开发者解锁新的自由与可能。

随着技术的不断发展,采用 Headless UI 将使开发人员能够保持领先地位,在您的下一个前端开发项目中探索 Headless UI 的强大功能并释放其变革潜力吧。


这是一个从 https://juejin.cn/post/7368413106676187151 下的原始话题分离的讨论话题