在Day06與Day07中,我們透過自然語言刻出原生的TailwindCSS卡片與ReactModal,並成功注入了表單驗證與狀態互動。
然而,手寫原生CSS或無障礙(Accessibility/a11y)互動元件(DropdownMenu、Dialog、Tooltip、Toast)非常耗時。直接使用專業的UI元件庫能大幅提升原型的精緻度與開發速度。
但在VibeCoding時,讓AI處理第三方元件庫經常遭遇套件毒藥陷阱:AI會隨心所欲地假想某些NPM套件或組件名稱存在(幻想有@shadcn/ui這個套件,或是調用根本不存在的Props),導致專案建置直接崩潰。
今天,我們將學習如何引導AI正確安裝、設定並調用當前最熱門的ShadcnUI元件庫。
1.為什麼選擇ShadcnUI?
傳統UI庫(AntDesign、MUI)是打包好的NPM大套件,客製化樣式時常需要覆蓋深層CSS。
ShadcnUI採用了全新的思維:它不是一個NPM套件,而是一個組件代碼生成器。它將可存取的無障礙底層(RadixUI)與TailwindCSS代碼直接拷貝到你的專案目錄(components/ui/)中,讓你能100%掌握組件代碼。這與VibeCoding+Cursor的代碼生成模式可謂天作之合!
2.避免AI幻覺:整合UI庫的三大鐵則
當你請AI使用第三方元件庫時,務必遵守以下鐵則:
鐵則1:別讓AI在Terminal瞎猜,先給予精準CLI命令
鐵則2:使用@docs或標明API,鎖定正版組件範例
鐵則3:讓AI優先讀取localcomponents/ui/內的原始代碼
先手動執行CLI或給予明確指令:ShadcnUI的組件需要透過npxshadcn@latestadd加入專案。若只對AI說用Shadcn的Dialog,AI可能會企圖直接從不存在的套件import{Dialog}from'shadcn-ui'。
使用@docs鎖定API語法:透過Cursor的@docs引入Shadcn官方文件,防止AI調用舊版RadixUI的舊屬性。
明確引導路徑:指示AI請從@/components/ui/dialog引入組件。
3.實戰演練:重構VibePulse的刪除確認Dialog與Toast通知
我們預計使用ShadcnUI的AlertDialog與Sonner(Toast)重構我們的系統提示邏輯。
步驟1:指令安裝Shadcn元件
在Terminal執行(或請AI產生Terminal指令):
npx shadcn@latest add alert-dialog sonner
步驟2:發送重構Prompt
開啟Cursor,對著@components/DeleteSkillDialog.tsx發送Prompt:
@components/ui/alert-dialog.tsx(參考專案內的Shadcn組件)
請幫我建立一個用於確認刪除技能的彈出對話框`DeleteSkillDialog.tsx`。
##需求說明:
1.使用組件:請使用`@/components/ui/alert-dialog`裡面的`AlertDialog`,`AlertDialogAction`,`AlertDialogCancel`,`AlertDialogContent`,`AlertDialogDescription`,`AlertDialogFooter`,`AlertDialogHeader`,`AlertDialogTitle`。
2.Props介面:
-`isOpen:boolean`
-`skillTitle:string`
-`onClose:()=>void`
-`onConfirm:()=>void`
3.視覺與文字:
-標題:確定要刪除{skillTitle}嗎?
-描述:此動作無法復原,該技能相關的所有學習日誌也將一併刪除。
-按鈕:取消(Cancel)、確認刪除(Destructive紅色樣式)。
4.Toast整合:
-當使用者點擊確認刪除時,觸發`onConfirm`並呼叫`toast.success("已成功刪除技能")`(從`sonner`引入)。
4.AI產出的重構程式碼
AI精準調用了local的Shadcn UI元件與Sonner Toast:
import React from 'react';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { toast } from 'sonner';
interface DeleteSkillDialogProps {
isOpen: boolean;
skillTitle: string;
onClose: () => void;
onConfirm: () => void;
}
export default function DeleteSkillDialog({
isOpen,
skillTitle,
onClose,
onConfirm,
}: DeleteSkillDialogProps) {
const handleConfirm = () => {
onConfirm();
toast.success(`已成功刪除「${skillTitle}」技能!`, {
description: '相關的學習日誌與進度已更新。',
});
onClose();
};
return (
<AlertDialog open={isOpen} onOpenChange={(open) => !open && onClose()}>
<AlertDialogContent className="bg-slate-900 border-slate-800 text-slate-100">
<AlertDialogHeader>
<AlertDialogTitle>確定要刪除「{skillTitle}」嗎?</AlertDialogTitle>
<AlertDialogDescription className="text-slate-400">
此動作無法復原。刪除後,該技能相關的歷程記錄與統計數據將一併移除。
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel
onClick={onClose}
className="border-slate-700 bg-slate-800 text-slate-300 hover:bg-slate-700 hover:text-white"
>
取消
</AlertDialogCancel>
<AlertDialogAction
onClick={handleConfirm}
className="bg-rose-600 hover:bg-rose-500 text-white shadow-lg shadow-rose-600/20"
>
確認刪除
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
}
今天我們解鎖了引入專業UI庫的最佳實踐:
避免了AI幻想不存在套件的典型崩潰。
透過CLI正確導入ShadcnUI原生代碼。
引導AI調用可存取(a11y)的專業無障礙元件,大幅提升VibePulse的產品完成度與細節質感。