关于 shadcn-vue
shadcn-vue 是面向 Vue 项目的 UI 组件与设计系统框架 Skill。它指导开发者通过 CLI 搜索、添加和更新源代码组件,并依据项目配置和组件组合规则进行操作。
主要功能
- 01在注册表中搜索组件
- 02将组件作为源码加入项目
- 03查看项目配置与已安装组件
- 04获取组件文档和示例
- 05指导安全更新组件
适用场景
- 01用现有组件构建 Vue 界面
- 02实现前核对组件 API
- 03为项目应用预设
- 04更新前审查上游改动
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ unovue/ shadcn-vue --skill shadcn-vue安装后在 Claude Code 中输入/shadcn-vue确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
cli.mdcustomization.mdmcp.mdrules/composition.mdforms.mdicons.mdstyling.md详细介绍
shadcn-vue
用于构建 UI、组件和设计系统的框架。组件通过 CLI 以源代码的形式添加到用户的项目中。
IMPORTANT: 所有 CLI 命令都要使用项目的包运行器:
npx shadcn-vue@latest、pnpm dlx shadcn-vue@latest或bunx --bun shadcn-vue@latest,具体取决于项目的packageManager。以下示例使用npx shadcn-vue@latest,请替换为项目对应的运行器。
当前项目上下文
!`npx shadcn-vue@latest info --json`
上面的 JSON 包含项目配置和已安装的组件。对于任何组件,使用 npx shadcn-vue@latest docs <component> 获取文档和示例 URL。
原则
- 优先使用现有组件。 编写自定义 UI 前,使用
npx shadcn-vue@latest search检查注册表。也要检查社区注册表。 - 组合使用,不要重复造轮子。 设置页面 = Tabs + Card + 表单控件。仪表板 = Sidebar + Card + Chart + Table。
- 优先使用内置变体,而不是自定义样式。
variant="outline"、size="sm"等。 - 使用语义化颜色。 使用
bg-primary、text-muted-foreground,不要使用bg-blue-500这类原始值。
关键规则
这些规则始终强制执行。每条规则都链接到包含错误/正确代码示例的文件。
样式与 Tailwind → styling.md
class用于布局,而非样式。 不要覆盖组件颜色或字体排版。- 不要使用
space-x-*或space-y-*。 使用flex搭配gap-*。垂直堆叠时,使用flex flex-col gap-*。 - 宽度和高度相等时使用
size-*。 使用size-10,而不是w-10 h-10。 - 使用
truncate简写。 不要使用overflow-hidden text-ellipsis whitespace-nowrap。 - 不要手动覆盖
dark:颜色。 使用语义化令牌(bg-background、text-muted-foreground)。 - 使用
cn()设置条件类。 不要手动编写模板字面量三元表达式。 - 不要在覆盖层组件上手动设置
z-index。 Dialog、Sheet、Popover 等会自行处理堆叠顺序。
表单与输入 → forms.md
- 表单使用
FieldGroup+Field。 不要使用带space-y-*或grid gap-*的原始div来布局表单。 InputGroup使用InputGroupInput/InputGroupTextarea。 不要在InputGroup内直接使用Input/Textarea。- 输入框内的按钮使用
InputGroup+InputGroupAddon。 - 选项集(2–7 个选项)使用
ToggleGroup。 不要循环渲染Button并手动管理激活状态。 - 使用
FieldSet+FieldLegend对相关复选框/单选框分组。 不要使用带标题的div。 - 字段验证使用
data-invalid+aria-invalid。 在Field上设置data-invalid,在控件上设置aria-invalid。禁用时:在Field上设置data-disabled,在控件上设置disabled。
组件结构 → composition.md
- 条目始终放在对应的 Group 中。
SelectItem→SelectGroup。DropdownMenuItem→DropdownMenuGroup。CommandItem→CommandGroup。 - Dialog、Sheet 和 Drawer 始终需要 Title。 为保证无障碍性,必须提供
DialogTitle、SheetTitle、DrawerTitle。若需视觉隐藏,请使用class="sr-only"。 - 使用完整的 Card 组合。 使用
CardHeader/CardTitle/CardDescription/CardContent/CardFooter。不要把所有内容都塞进CardContent。 - Button 没有
isPending/isLoading。 使用Spinner+data-icon+disabled进行组合。 TabsTrigger必须放在TabsList内。 不要直接在Tabs中渲染触发器。Avatar始终需要AvatarFallback。 用于图片加载失败时的回退显示。
使用组件,而非自定义标记 → composition.md
- 优先使用现有组件,而非自定义标记。 编写带样式的
div之前,先检查是否已有对应组件。 - 提示框使用
Alert。 不要构建自定义样式的 div。 - 空状态使用
Empty。 不要构建自定义空状态标记。 - 通过
vue-sonner显示 Toast。 使用vue-sonner中的toast()。 - 使用
Separator,而不是<hr>或<div class="border-t">。 - 使用
Skeleton作为加载占位符。不要使用自定义的animate-pulsediv。 - 使用
Badge,而不是自定义样式的 span。
图标 → icons.md
Button中的图标使用data-icon。 在图标上设置data-icon="inline-start"或data-icon="inline-end"。- 组件内部的图标不要设置尺寸类。 组件会通过 CSS 处理图标尺寸。不要使用
size-4或w-4 h-4。 - 将图标作为对象传递,而不是字符串键。 使用
:icon="CheckIcon",而不是字符串查找。
CLI
- 直接使用 CLI 应用预设代码。 对于现有项目,使用
npx shadcn-vue@latest apply <code>;初始化项目时,使用npx shadcn-vue@latest init --preset <code>。
关键模式
以下是区分正确 shadcn-vue 代码的最常见模式。特殊情况请参阅上方链接的规则文件。
<FieldGroup>
<Field>
<FieldLabel for="email">Email</FieldLabel>
<Input id="email" />
</Field>
</FieldGroup>
<Field data-invalid>
<FieldLabel>Email</FieldLabel>
<Input aria-invalid />
<FieldDescription>Invalid email.</FieldDescription>
</Field>
<Button>
<SearchIcon data-icon="inline-start" />
Search
</Button>
<div class="flex flex-col gap-4">
<div class="space-y-4">
<Avatar class="size-10">
<Avatar class="w-10 h-10">
<Badge variant="secondary">+20.1%</Badge>
<span class="text-emerald-600">+20.1%</span>
组件选择
| 需求 | 使用 |
|---|---|
| 按钮/操作 | Button 和合适的变体 |
| 表单输入 | Input、Select、Combobox、Switch、Checkbox、RadioGroup、Textarea、InputOTP、Slider |
| 在 2–7 个选项间切换 | ToggleGroup + ToggleGroupItem |
| 数据展示 | Table、Card、Badge、Avatar |
| 导航 | Sidebar、NavigationMenu、Breadcrumb、Tabs、Pagination |
| 覆层 | Dialog(模态框)、Sheet(侧边面板)、Drawer(底部面板)、AlertDialog(确认) |
| 反馈 | vue-sonner(Toast)、Alert、Progress、Skeleton、Spinner |
| 命令面板 | Dialog 中的 Command |
| 图表 | Chart(封装 Unovis) |
| 布局 | Card、Separator、Resizable、ScrollArea、Accordion、Collapsible |
| 空状态 | Empty |
| 菜单 | DropdownMenu、ContextMenu、Menubar |
| 工具提示/信息 | Tooltip、HoverCard、Popover |
关键字段
注入的项目上下文包含以下关键字段:
aliases→ 导入时使用实际的别名前缀(例如@/、~/),不要硬编码。tailwindVersion→"v4"使用@theme inline块;"v3"使用tailwind.config.js。tailwindCssFile→ 定义自定义 CSS 变量的全局 CSS 文件。始终编辑此文件,不要创建新文件。style→ 组件的视觉样式(例如nova、vega)。base→ 基础组件库(reka)。会影响组件 API 和可用属性。iconLibrary→ 决定图标导入方式。lucide使用@lucide/vue,tabler使用@tabler/icons-vue,以此类推。不要想当然地使用@lucide/vue。resolvedPaths→ 组件、工具函数、钩子等的确切文件系统目标路径。framework→ 路由和文件约定(例如 Nuxt 与 Vite SPA)。packageManager→ 安装任何非 shadcn-vue 依赖时使用该包管理器(例如pnpm add date-fns与npm install date-fns)。
完整字段参考请参阅 cli.md — info 命令。
组件文档、示例和用法
运行 npx shadcn-vue@latest docs <component> 获取组件文档、示例和 API 参考的 URL。获取这些 URL 的内容。
npx shadcn-vue@latest docs button dialog select
创建、修复、调试或使用组件时,务必先运行 npx shadcn-vue@latest docs 并获取这些 URL。 这样可以确保你使用的是正确的 API 和用法,而不是凭空猜测。
工作流
- 获取项目上下文 — 已在上方注入。如果需要刷新,请再次运行
npx shadcn-vue@latest info。 - 先检查已安装的组件 — 运行
add之前,务必先查看项目上下文中的components列表,或列出resolvedPaths.ui目录。不要导入尚未添加的组件,也不要重复添加已安装的组件。 - 查找组件 — 运行
npx shadcn-vue@latest search。 - 获取文档和示例 — 运行
npx shadcn-vue@latest docs <component>获取 URL,然后访问这些 URL。使用npx shadcn-vue@latest view浏览尚未安装的注册表项目。若要预览已安装组件的更改,请使用npx shadcn-vue@latest add --diff。 - 安装或更新 — 运行
npx shadcn-vue@latest add。更新现有组件时,先使用--dry-run和--diff预览更改(参见下文的更新组件)。 - 修复第三方组件中的导入路径 — 添加社区注册表中的组件后,请检查新增的非 UI 文件,查找类似
@/components/ui/...的硬编码导入路径。这些路径可能与项目实际使用的别名不匹配。运行npx shadcn-vue@latest info获取正确的ui别名(例如@workspace/ui/components),并相应地重写导入路径。CLI 会重写其自身 UI 文件中的导入路径,但第三方注册表组件可能使用与项目不匹配的默认路径。 - 检查新增组件 — 从任何注册表添加组件或区块后,务必阅读新增文件并确认其正确无误。检查是否缺少子组件(例如,有
SelectItem却没有SelectGroup)、缺少导入、组合方式错误,或违反了关键规则。还要将所有图标导入替换为项目上下文中的iconLibrary(例如,若注册表项目使用@lucide/vue,而项目使用hugeicons,请相应替换导入路径和图标名称)。解决所有问题后再继续。 - 必须明确指定注册表 — 用户要求添加区块或组件时,不要猜测注册表。如果用户未指定注册表(例如用户只说“添加一个登录区块”,没有指定
@shadcn等注册表),请询问要使用哪个注册表。切勿擅自替用户选择注册表。 - 切换预设 — 先询问用户选择:覆盖、合并还是跳过?
- 覆盖:
npx shadcn-vue@latest apply <code>。覆盖检测到的组件、字体和 CSS 变量。 - 合并:运行
npx shadcn-vue@latest init --preset <code> --force --no-reinstall,然后运行npx shadcn-vue@latest info列出已安装的组件,再对每个已安装的组件使用--dry-run和--diff,逐个进行智能合并。 - 跳过:
npx shadcn-vue@latest init --preset <code> --force --no-reinstall。仅更新配置和 CSS,保留组件不变。 - 重要:务必在用户的项目目录中运行预设命令。
apply仅适用于包含components.json文件的现有项目。CLI 会自动保留components.json中当前的基础(reka)。如果必须使用临时目录(例如用于--dry-run比较),请显式传入--base <current-base>— 预设代码中不包含基础信息。
- 覆盖:
更新组件
当用户要求从上游更新组件,同时保留本地更改时,使用 --dry-run 和 --diff 进行智能合并。切勿手动从 GitHub 获取原始文件——始终使用 CLI。
- 运行
npx shadcn-vue@latest add <component> --dry-run,查看所有可能受影响的文件。 - 对每个文件运行
npx shadcn-vue@latest add <component> --diff <file>,查看上游与本地的更改。 - 根据差异逐个文件做出决定:
- 没有本地更改 → 可以安全覆盖。
- 存在本地更改 → 阅读本地文件,分析差异,并在保留本地修改的同时应用上游更新。
- 用户表示“全部更新” → 使用
--overwrite,但须先确认。
- 未经用户明确批准,绝不使用
--overwrite。
快速参考
# Create a new project.
npx shadcn-vue@latest init --name my-app --preset nova
npx shadcn-vue@latest init --name my-app --preset a2r6bw --template vite
# Initialize existing project.
npx shadcn-vue@latest init --preset nova
npx shadcn-vue@latest init --defaults # shortcut: --template=nuxt --preset=nova (base style implied)
# Apply a preset to an existing project.
npx shadcn-vue@latest apply a2r6bw
# Add components.
npx shadcn-vue@latest add button card dialog
npx shadcn-vue@latest add --all
# Search registries.
npx shadcn-vue@latest search @shadcn -q "sidebar"
# Get component docs and example URLs.
npx shadcn-vue@latest docs button dialog select
# View registry item details (for items not yet installed).
npx shadcn-vue@latest view @shadcn/button
命名预设: nova、vega、maia、lyra、mira、luma
模板: nuxt、vite、astro 和 laravel
预设代码: 带版本前缀的 base62 字符串(例如 a2r6bw),来自 shadcn-vue.com。
详细参考
- rules/forms.md — FieldGroup、Field、InputGroup、ToggleGroup、FieldSet、验证状态
- rules/composition.md — 组、覆盖层、Card、Tabs、Avatar、Alert、Empty、Toast、Separator、Skeleton、Badge、Button 加载状态
- rules/icons.md — data-icon、图标尺寸、将图标作为对象传递
- rules/styling.md — 语义颜色、变体、class、间距、尺寸、截断、深色模式、cn()、z-index
- cli.md — 命令、标志、预设、模板
- customization.md — 主题设置、CSS 变量、扩展组件