把「Headless UI」跟「传统 UI」的区别,用一句话先讲清:
传统 UI 是“给你一整套已经装修好的房子”;
Headless UI 是“只给你毛坯房 + 乐高积木”,外观你自己搭,功能它全包。
下面用“3 张图 + 3 个例子 + 3 步落地”带你从零看懂并真正用起来。
──────────────────
一、设计理念对比(一张表看懂)
| 维度 | 传统 UI(如 Element Plus) | Headless UI(如 HeadlessUI、Radix) |
|---|---|---|
| 外观 | 自带主题色、圆角、阴影 | 0 样式,只提供 HTML + JS 逻辑 |
| 定制 | 用 SASS 变量、CSS 覆盖 | 完全自由写 CSS / Tailwind / Styled-components |
| 包体积 | 组件 + 样式一起打包 | 只打包逻辑,样式按需 |
| 无障碍 | 部分框架已做 | 官方强制做,ARIA、键盘导航一步到位 |
| 设计一致性 | 统一但难跳出框架风格 | 完全由你决定,不打架 |
──────────────────
二、3 个生活化例子
-
按钮
• 传统:<el-button type="primary">保存</el-button>永远是蓝底白字。
• Headless:<Button>保存</Button>渲染出来只是一个裸<button>,你想让它变红/圆角/带图标,全靠你自己写 CSS 或 Tailwind:class="bg-red-500 rounded px-4"。 -
对话框
• 传统:<el-dialog>自带遮罩、关闭图标、动画。
• Headless:<Dialog>只帮你管“打开/关闭、焦点管理、ESC 关闭”三件事,遮罩层、动画全靠你包一层 div 写样式。 -
下拉菜单
• 传统:<el-dropdown>样式固定,想改三角箭头颜色得翻源码。
• Headless:<Menu>只提供“键盘↑↓导航、点击外部关闭”逻辑,弹出框你爱怎么画就怎么画。
──────────────────
三、初学者 3 步落地法
Step1:选一个「Headless 库」
• React:@headlessui/react 或 Radix UI
• Vue3:@headlessui/vue
• Angular:Angular CDK Overlay/Menu
Step2:用「原子化 CSS」或「CSS Modules」
• 最快:Tailwind CSS(一行 class 就能拼出外观)
• 设计系统:自己写 CSS Modules / Styled-components
例子(Vue3 + Tailwind):
<template>
<Menu as="div" class="relative">
<MenuButton class="rounded bg-indigo-600 px-4 py-2 text-white">
操作
</MenuButton>
<MenuItems class="absolute mt-2 w-32 rounded bg-white shadow-lg">
<MenuItem v-slot="{ active }">
<a :class="{ 'bg-gray-100': active }" class="block px-4 py-2">编辑</a>
</MenuItem>
<MenuItem v-slot="{ active }">
<a :class="{ 'bg-gray-100': active }" class="block px-4 py-2">删除</a>
</MenuItem>
</MenuItems>
</Menu>
</template>
Step3:把「常用组件」封装成公司级小库
• 用 HeadlessUI 的 <Dialog> 包一层,统一遮罩、动画、按钮位置 → 得到内部 <MyDialog>
• 以后所有项目直接 import MyDialog from '@corp/headless-ext',既保持视觉一致,又避免重复写样式。
──────────────────
一句话总结
Headless UI = 逻辑 100 % 给你,外观 0 % 限制;
只要记住「功能它管、长啥样你管」,再配合 Tailwind 或自家设计系统,你就能在 1 天内搭出既好看又不撞衫的组件库。
-
Headless UI 适合:需要高度定制、跨平台、复杂交互的项目。
-
传统 UI 适合:快速原型、设计规范统一的中后台系统。
学习路径:先掌握传统 UI → 理解 Headless 的逻辑分离 → 逐步替换组件 → 构建完整设计系统。通过小项目实践(如登录页、表单),逐步适应 Headless 的开发模式。