管理 shadcn-vue 元件與專案 — 新增、搜尋、修復、除錯、樣式設定與 UI 組合。提供專案上下文、元件文件與使用範例。適用於操作 shadcn-vue、元件註冊表、預設組、--preset 代碼,或任何包含 components.json 檔案的專案。也觸發於「shadcn-vue init」、「使用 --preset 建立應用程式」或「切換至 --preset」。
shadcn-vue
一個用於建構 UI、元件與設計系統的框架。元件會透過 CLI 以原始碼形式新增至使用者的專案中。
重要: 所有 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> 可取得任何元件的文件與範例網址。
原則
- 優先使用現有元件。 在撰寫自訂 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:顏色覆寫。 使用語意化 token(bg-background、text-muted-foreground)。 - 使用
cn()處理條件式 class。 不要手寫模板字串三元運算式。 - 覆蓋層元件上禁止手動設定
z-index。 Dialog、Sheet、Popover 等會自行處理堆疊。
表單與輸入 → forms.md
- 表單使用
FieldGroup+Field。 絕不使用原始的div搭配space-y-*或grid gap-*來做表單佈局。 InputGroup使用InputGroupInput/InputGroupTextarea。 絕不在InputGroup內使用原始的Input/Textarea。- 輸入框內的按鈕使用
InputGroup+InputGroupAddon。 - 選項集合(2–7 個選項)使用
ToggleGroup。 不要用Button迴圈搭配手動 active 狀態。 - 使用
FieldSet+FieldLegend來群組相關的 checkbox/radio。 不要用div搭配標題。 - 欄位驗證使用
data-invalid+aria-invalid。data-invalid放在Field上,aria-invalid放在控制項上。禁用狀態:data-disabled放在Field上,disabled放在控制項上。
元件結構 → composition.md
- 項目一律放在其 Group 內。
SelectItem→SelectGroup。DropdownMenuItem→DropdownMenuGroup。CommandItem→CommandGroup。 - Dialog、Sheet 和 Drawer 一律需要標題。 為無障礙性必須有
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。 不要自訂空狀態標記。 - Toast 使用
vue-sonner。 從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"。 - 元件內部的圖示不要加上尺寸 class。 元件會透過 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,而非 div + Label。 -->
<FieldGroup>
<Field>
<FieldLabel for="email">Email</FieldLabel>
<Input id="email" />
</Field>
</FieldGroup>
<!-- 驗證:data-invalid 在 Field 上,aria-invalid 在控制項上。 -->
<Field data-invalid>
<FieldLabel>Email</FieldLabel>
<Input aria-invalid />
<FieldDescription>無效的 Email。</FieldDescription>
</Field>
<!-- 按鈕中的圖示:data-icon,無尺寸 class。 -->
<Button>
<SearchIcon data-icon="inline-start" />
搜尋
</Button>
<!-- 間距:gap-*,而非 space-y-*。 -->
<div class="flex flex-col gap-4"> <!-- 正確 -->
<div class="space-y-4"> <!-- 錯誤 -->
<!-- 相等尺寸:size-*,而非 w-* h-*。 -->
<Avatar class="size-10"> <!-- 正確 -->
<Avatar class="w-10 h-10"> <!-- 錯誤 -->
<!-- 狀態顏色:Badge 變體或語意化 token,而非原始顏色。 -->
<Badge variant="secondary">+20.1%</Badge> <!-- 正確 -->
<span class="text-emerald-600">+20.1%</span> <!-- 錯誤 -->
元件選擇
| 需求 | 使用 |
|---|---|
| 按鈕/動作 | Button 搭配適當的 variant |
| 表單輸入 | 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 |
| 指令面板 | Command 放在 Dialog 內 |
| 圖表 | 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 與可用 props。iconLibrary→ 決定圖示匯入方式。lucide使用@lucide/vue,tabler使用@tabler/icons-vue等。絕不預設為@lucide/vue。resolvedPaths→ 元件、工具函式、hooks 等的確切檔案系統路徑。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 參考網址。請擷取這些網址以取得實際內容。
npx shadcn-vue@latest docs button dialog select
在建立、修復、除錯或使用元件時,一律先執行 npx shadcn-vue@latest docs 並擷取網址。 這樣可確保您使用的是正確的 API 與使用模式,而非猜測。
工作流程
- 取得專案上下文 — 已在上方注入。若需重新整理,請再次執行
npx shadcn-vue@latest info。 - 先檢查已安裝的元件 — 在執行
add之前,一律從專案上下文檢查components列表,或列出resolvedPaths.ui目錄。不要匯入尚未新增的元件,也不要重新新增已安裝的元件。 - 尋找元件 —
npx shadcn-vue@latest search。 - 取得文件與範例 — 執行
npx shadcn-vue@latest docs <component>取得網址,然後擷取內容。使用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中的目前 base(reka)。若必須使用暫存目錄(例如進行--dry-run比較),請明確傳入--base <current-base>— 預設組代碼不包含 base 資訊。
- 覆寫:
更新元件
當使用者要求從上游更新元件但保留本地變更時,請使用 --dry-run 和 --diff 進行智慧合併。絕不手動從 GitHub 擷取原始檔案 — 一律使用 CLI。
- 執行
npx shadcn-vue@latest add <component> --dry-run查看所有受影響的檔案。 - 對每個檔案,執行
npx shadcn-vue@latest add <component> --diff <file>查看上游與本地的差異。 - 根據差異逐檔決定:
- 無本地變更 → 可安全覆寫。
- 有本地變更 → 讀取本地檔案,分析差異,並在保留本地修改的同時套用上游更新。
- 使用者說「直接全部更新」 → 使用
--overwrite,但需先確認。
- 未經使用者明確同意,絕不使用
--overwrite。
快速參考
# 建立新專案。
npx shadcn-vue@latest init --name my-app --preset nova
npx shadcn-vue@latest init --name my-app --preset a2r6bw --template vite
# 初始化現有專案。
npx shadcn-vue@latest init --preset nova
npx shadcn-vue@latest init --defaults # 快捷:--template=nuxt --preset=nova(基礎樣式隱含)
# 對現有專案套用預設組。
npx shadcn-vue@latest apply a2r6bw
# 新增元件。
npx shadcn-vue@latest add button card dialog
npx shadcn-vue@latest add --all
# 搜尋註冊表。
npx shadcn-vue@latest search @shadcn -q "sidebar"
# 取得元件文件與範例網址。
npx shadcn-vue@latest docs button dialog select
# 檢視註冊表項目詳細資訊(針對尚未安裝的項目)。
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 — Groups、覆蓋層、Card、Tabs、Avatar、Alert、Empty、Toast、Separator、Skeleton、Badge、Button 載入狀態
- rules/icons.md — data-icon、圖示尺寸、將圖示作為物件傳遞
- rules/styling.md — 語意化顏色、變體、class、間距、尺寸、truncate、深色模式、cn()、z-index
- cli.md — 指令、旗標、預設組、範本
- customization.md — 主題設定、CSS 變數、擴充元件






