Radix UI 无头组件库实战指南

Sarah Wong | 2026-09-02T01:07:05 | JavaScript, Frontend

介绍 Radix UI 的设计理念和核心组件,演示如何基于 Radix Primitives 搭建完全自定义样式的无障碍 UI 组件库。

# Radix UI 无头组件库实战指南 ## 什么是无头组件 无头组件(Headless Components)提供了完整的交互逻辑和无障碍支持,但不包含任何样式。开发者可以用自己的 CSS 方案自由定制外观,同时享受经过充分测试的行为层。 Radix UI 是这个领域的佼佼者,被 shadcn/ui 等流行组件库作为底层依赖。 ## 安装 ```bash npm install @radix-ui/react-dialog @radix-ui/react-dropdown-menu \ @radix-ui/react-tooltip @radix-ui/react-tabs @radix-ui/react-select ``` ## Dialog 对话框 ```tsx import * as Dialog from "@radix-ui/react-dialog"; function ConfirmDialog({ onConfirm }) { return ( Delete Confirm Deletion This action cannot be undone. Are you sure? Cancel Delete X ); } ``` 自定义样式: ```css .dialog-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); animation: fadeIn 150ms ease; } .dialog-content { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: var(--bg-primary); border-radius: 12px; padding: 24px; max-width: 480px; width: 90vw; box-shadow: 0 24px 48px rgba(0, 0, 0, 0.2); animation: contentShow 200ms ease; } ``` ## DropdownMenu ```tsx import * as DropdownMenu from "@radix-ui/react-dropdown-menu"; function UserMenu({ user, onLogout }) { return ( {user.name} navigate("/profile")}> Profile navigate("/settings")}> Settings Log Out ); } ``` ## 无障碍支持 Radix 自动处理了大量 a11y 细节: - **键盘导航**:Tab、方向键、Enter、Escape 全部正确处理 - **焦点管理**:Dialog 打开自动聚焦,关闭后恢复焦点 - **ARIA 属性**:自动添加 role、aria-expanded、aria-haspopup 等 - **屏幕阅读器**:所有状态变化都有正确的语义通知 你只需关注视觉样式,行为层已经完备。 ## 与 Tailwind CSS 配合 ```tsx ``` Radix 使用 `data-state` 属性标记组件状态,可以直接用 Tailwind 的数据属性选择器来添加动画。 ## 封装自己的组件库 推荐用 Radix 作为底层,封装业务组件库: ```tsx // components/ui/modal.tsx import * as Dialog from "@radix-ui/react-dialog"; interface ModalProps { open: boolean; onOpenChange: (open: boolean) => void; title: string; children: React.ReactNode; } export function Modal({ open, onOpenChange, title, children }: ModalProps) { return ( {title} {children} ); } ``` ## 总结 Radix UI 的无头组件理念让你专注于设计系统的视觉层,而不用担心交互逻辑和无障碍支持。它是 shadcn/ui 的基石,也是构建自定义组件库的最佳选择。

← Back to Blog