shadcn/ui
文章目录
- 前言
- ✅ 核心特点
- 📦 支持组件(常用)
- 🚀 安装使用(框架支持)
- 初始化(Next.js 项目为例)
- 添加一个组件
- 🧠 对比其他组件库
- 📘 官方资源
- ✅ 总结
- ✅ 功能特性:
- 📦 依赖项(需先安装)
- 🧱 页面代码:`ChatPage.tsx`
- 🎨 可选样式增强(全局 CSS)
- 🧪 进一步可添加功能
前言
shadcn/ui
是一个由社区维护的现代 UI 组件库模板集合,专为 React + Tailwind CSS 生态设计,主打:
- ✨ 可完全控制样式 &行为(不像 MUI、AntD 那样封闭)
- 🎯 基于 Radix UI(可访问性强)
- 🧩 可选的组件拼装,不强绑设计系统
- ⚙️ 支持 Server Component、SSR、RSC 等现代特性
✅ 核心特点
特性 | 说明 |
---|---|
✨ 美观现代 | 默认采用干净、优雅的设计(类似 Vercel / Linear) |
🎨 Tailwind 驱动 | 100% Tailwind CSS 控制样式,自由修改 |
⚛️ Radix UI 底层 | 提供无障碍可访问性支持(A11y) |
🧱 可组合 | 所有组件是“导入代码”的方式,无 run-time 限制 |
🔧 可维护性强 | 你拥有组件代码本体(不再受限组件黑箱) |
📦 支持组件(常用)
分类 | 组件 |
---|---|
表单 | Input , Textarea , Select , Switch , Checkbox , Form |
弹窗 | Dialog , Popover , Tooltip , AlertDialog , Sheet |
导航 | Tabs , Accordion , DropdownMenu , NavigationMenu |
其他 | Toast , Badge , Card , Avatar , Skeleton , Progress |
🚀 安装使用(框架支持)
支持 Vite、Next.js、Remix 等现代 React 框架。
初始化(Next.js 项目为例)
npx shadcn-ui@latest init
你会被提示:
- 是否使用 TypeScript
- UI 目录位置(如
components/ui
) - Tailwind 配置路径
- 是否安装组件(如
Button
,Dialog
)
添加一个组件
npx shadcn-ui@latest add button
生成的文件:
components/ui/button.tsx
你可以自由修改样式类或行为。
🧠 对比其他组件库
特性 | shadcn/ui | MUI | Ant Design | Chakra UI |
---|---|---|---|---|
样式控制 | ✅ 完全控制 | ❌ 封闭 | ❌ 封闭 | ⚠️ 类似 |
设计系统 | ⚠️ 提供默认样式 | ✅ 有 | ✅ 有 | ✅ 有 |
SSR 支持 | ✅ 优秀 | ⚠️ 需调整 | ⚠️ 有限 | ⚠️ 有限 |
适合 Tailwind | ✅ 最佳搭配 | ❌ 不兼容 | ❌ 不兼容 | ❌ 有冲突 |
📘 官方资源
- 官网:https://ui.shadcn.com
- GitHub:https://github.com/shadcn-ui/ui
- Demo 示例:https://ui.shadcn.com/docs/components/slider
✅ 总结
适合你吗? | 条件 |
---|---|
✅ 喜欢 Tailwind | 强烈推荐 |
✅ 需要 SSR / RSC 兼容 | 推荐 |
✅ 想要样式可控且干净 UI | 推荐 |
❌ 想要“开箱即用 + Theme切换 + 组件黑盒” | 不太适合 |
下面是一个基于 shadcn/ui
、React
和 Tailwind CSS
封装的 AI 聊天界面模板,具备如下特性:
✅ 功能特性:
- 支持聊天消息滚动显示
- 用户输入框 + 发送按钮
- 显示用户消息和 AI 消息
- 使用
shadcn/ui
组件:Input
,Button
,Card
,ScrollArea
,Skeleton
- Tailwind 风格美观整洁
📦 依赖项(需先安装)
npx shadcn-ui@latest init
npx shadcn-ui@latest add button input card scroll-area
🧱 页面代码:ChatPage.tsx
import { useState, useRef, useEffect } from "react"
import { Input } from "@/components/ui/input"
import { Button } from "@/components/ui/button"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Card, CardContent } from "@/components/ui/card"interface Message {role: "user" | "assistant"content: string
}export default function ChatPage() {const [messages, setMessages] = useState<Message[]>([])const [input, setInput] = useState("")const scrollRef = useRef<HTMLDivElement>(null)const handleSend = async () => {if (!input.trim()) returnconst userMsg: Message = { role: "user", content: input }setMessages((prev) => [...prev, userMsg])setInput("")// 模拟 AI 回复setTimeout(() => {const aiMsg: Message = {role: "assistant",content: `你说的是:“${userMsg.content}”`}setMessages((prev) => [...prev, aiMsg])}, 1000)}useEffect(() => {scrollRef.current?.scrollIntoView({ behavior: "smooth" })}, [messages])return (<div className="flex flex-col h-screen p-4 max-w-2xl mx-auto"><h2 className="text-2xl font-bold mb-4">AI Chat Assistant</h2><ScrollArea className="flex-1 border rounded-lg p-4 space-y-2 bg-muted">{messages.map((msg, index) => (<Card key={index} className={msg.role === "user" ? "ml-auto bg-white" : "mr-auto bg-gray-100"}><CardContent className="p-3 text-sm whitespace-pre-wrap"><strong>{msg.role === "user" ? "You" : "AI"}:</strong> {msg.content}</CardContent></Card>))}<div ref={scrollRef} /></ScrollArea><div className="mt-4 flex gap-2"><Inputplaceholder="Ask something..."value={input}onChange={(e) => setInput(e.target.value)}onKeyDown={(e) => e.key === "Enter" && handleSend()}/><Button onClick={handleSend}>Send</Button></div></div>)
}
🎨 可选样式增强(全局 CSS)
body {@apply bg-background text-foreground;
}
🧪 进一步可添加功能
功能 | shadcn 组件建议 |
---|---|
Markdown 渲染 | react-markdown 自定义卡片内容 |
Skeleton 骨架 | Skeleton 组件用于 AI 回复加载中 |
多轮对话滚动 | ScrollArea + useRef 自动滚动到底部 |
AI 流式回复 | 用 useEffect 模拟逐字加载即可 |