适用人群:React/Next.js 开发者
难度:低-中
预计学习时间:5-10小时
什么是 Shadcn/UI?
不是传统组件库,而是可复制粘贴的组件集合。基于 Radix UI + Tailwind CSS,直接将组件源码复制到你的项目中,完全可控、可定制。
| 特点 | 说明 |
|---|---|
| 不是npm包 | 组件代码直接在你的项目中 |
| 完全可控 | 可以随意修改任何组件 |
| 可访问 | 基于 Radix UI,内置无障碍支持 |
| 美观 | 默认设计精美,暗色模式支持 |
| 流行 | 2024-2025最火的React组件方案 |
快速上手
# 创建Next.js项目
npx create-next-app@latest my-app --typescript --tailwind
cd my-app
# 初始化shadcn
npx shadcn@latest init
# 添加组件
npx shadcn@latest add button
npx shadcn@latest add card
npx shadcn@latest add input
npx shadcn@latest add dialog
npx shadcn@latest add table
npx shadcn@latest add form
npx shadcn@latest add toast
npx shadcn@latest add dropdown-menu
npx shadcn@latest add sheet
npx shadcn@latest add tabs
组件示例
// 使用 Button
import { Button } from '@/components/ui/button'
export function MyComponent() {
return (
<div className="flex gap-2">
<Button>默认按钮</Button>
<Button variant="secondary">次要按钮</Button>
<Button variant="destructive">危险按钮</Button>
<Button variant="outline">轮廓按钮</Button>
<Button variant="ghost">幽灵按钮</Button>
<Button variant="link">链接按钮</Button>
<Button size="sm">小按钮</Button>
<Button size="lg">大按钮</Button>
<Button disabled>禁用</Button>
</div>
)
}
// Card组件
import {
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
CardFooter
} from '@/components/ui/card'
export function PostCard() {
return (
<Card className="w-[350px]">
<CardHeader>
<CardTitle>文章标题</CardTitle>
<CardDescription>文章描述...</CardDescription>
</CardHeader>
<CardContent>
<p>文章内容...</p>
</CardContent>
<CardFooter className="flex justify-between">
<Button variant="outline">取消</Button>
<Button>确认</Button>
</CardFooter>
</Card>
)
}
// Dialog弹窗
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger
} from '@/components/ui/dialog'
export function MyDialog() {
return (
<Dialog>
<DialogTrigger asChild>
<Button>打开弹窗</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>确认操作</DialogTitle>
<DialogDescription>确定要执行此操作吗?</DialogDescription>
</DialogHeader>
<div className="flex justify-end gap-2">
<Button variant="outline">取消</Button>
<Button>确认</Button>
</div>
</DialogContent>
</Dialog>
)
}
// DataTable表格
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow
} from '@/components/ui/table'
export function DataTable() {
return (
<Table>
<TableHeader>
<TableRow>
<TableHead>姓名</TableHead>
<TableHead>邮箱</TableHead>
<TableHead>角色</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>Alice</TableCell>
<TableCell>alice@example.com</TableCell>
<TableCell>管理员</TableCell>
</TableRow>
</TableBody>
</Table>
)
}
// Form表单(配合react-hook-form + zod)
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import * as z from 'zod'
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'
import { Input } from '@/components/ui/input'
const formSchema = z.object({
username: z.string().min(2, '至少2个字符'),
email: z.string().email('请输入有效邮箱'),
})
export function MyForm() {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: { username: '', email: '' }
})
function onSubmit(values: z.infer<typeof formSchema>) {
console.log(values)
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<FormField control={form.control} name="username" render={({ field }) => (
<FormItem>
<FormLabel>用户名</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="email" render={({ field }) => (
<FormItem>
<FormLabel>邮箱</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<Button type="submit">提交</Button>
</form>
</Form>
)
}
常用组件列表
| 组件 | 命令 | 用途 |
|---|---|---|
| Button | add button | 按钮 |
| Card | add card | 卡片容器 |
| Input | add input | 输入框 |
| Dialog | add dialog | 弹窗 |
| Table | add table | 表格 |
| Form | add form | 表单 |
| Toast | add toast | 消息提示 |
| Tabs | add tabs | 标签页 |
| Select | add select | 下拉选择 |
| Sheet | add sheet | 侧边栏弹窗 |
| Dropdown Menu | add dropdown-menu | 下拉菜单 |
| Command | add command | 命令面板 |
| Calendar | add calendar | 日历 |
| Chart | add chart | 图表 |
推荐资源
| 资源 | 说明 |
|---|---|
| ui.shadcn.com | 官方文档和组件预览 |
| shadcnui.ai | AI生成组件 |
| Taxonomy | 官方示例项目 |
| Aceternity UI | shadcn风格动画组件 |