掌握 shadcn/ui:从安装、配置到实战技巧 – wiki基地


掌握 shadcn/ui:从安装、配置到实战技巧

前言

在现代前端开发中,React 组件库极大地提升了我们的开发效率。然而,传统的组件库如 Material-UI 或 Ant Design,虽然功能强大,但也常常因为过度封装、样式定制困难、打包体积过大等问题而受到诟病。

shadcn/ui 提供了一种全新的思路。它不是一个传统的组件库,而是一组可重用的、无障碍的、样式自由的组件集合。你可以通过命令行工具将这些组件直接引入到你的项目中,它们就成为了你自己的代码,你可以随心所欲地修改和扩展。

本文将带你深入了解 shadcn/ui,从零开始,一步步掌握其安装、配置、使用及高级技巧,帮助你构建出既美观又高效的应用程序。

什么是 shadcn/ui?

在我们开始之前,最重要的一点是:shadcn/ui 不是一个组件库

它更像是一个“组件代码生成器”。当你需要一个按钮(Button)时,你不是从一个 npm 包中导入 Button 组件,而是运行一个命令,这个命令会将 Button 组件的源代码(一个 React 组件文件)直接复制到你的项目源码目录中。

这种模式带来了几个核心优势:

  • 完全所有权:组件代码就在你的项目中,你可以像对待自己写的代码一样,完全控制它的逻辑、样式和行为。
  • 易于定制:由于代码是你的,修改样式或功能变得非常直接。你不需要通过复杂的 props 或者 CSS-in-JStheme 来覆盖默认样式。直接修改组件的 className 或者 JSX 结构即可。
  • 最小打包体积:你的应用最终打包时,只会包含你实际使用的组件代码,不会引入任何额外的、你不需要的库代码。
  • 基于 Tailwind CSSshadcn/ui 的所有组件都使用 Tailwind CSS 进行样式设计,如果你熟悉 Tailwind,那么定制样式会非常得心应手。

一、安装与配置

1. 环境准备

在开始之前,请确保你的开发环境满足以下要求:

  • Node.js (v14.0.0 或更高版本)
  • 一个基于 React 的项目(推荐使用 Next.js,但 Create React App 或其他框架也可以)
  • 项目中已经配置好 Tailwind CSS

如果你的项目还没有配置 Tailwind CSS,请先根据 Tailwind CSS 官方文档 进行安装和配置。

2. 初始化 shadcn/ui

打开你的项目根目录,在终端中运行以下命令:

bash
npx shadcn-ui@latest init

这个命令会引导你完成一系列的配置选项:

  • Would you like to use TypeScript (recommended)? (yes / no)
    > 建议选择 yesshadcn/ui 对 TypeScript 有着良好的支持。

  • Which style would you like to use? (Default / New York)
    > 这是两种预设的视觉风格,Default 更加简约,New York 则更具现代感。你可以随时在 components.json 文件中更改。

  • Which color would you like to use as base color? (Slate / Gray / Zinc / Neutral / Stone)
    > 选择一个基础色系,它会影响所有组件的默认颜色。

  • Where is your global.css?
    > 指定你的全局 CSS 文件路径,通常是 app/globals.csssrc/index.css

  • Would you like to use CSS variables for theming? (yes / no)
    > 强烈建议选择 yes,这会让你在后续实现主题切换(如深色模式)时变得非常容易。

  • Where is your tailwind.config.js (or tailwind.config.ts)?
    > 指定你的 Tailwind CSS 配置文件路径。

  • Configure import alias for components?
    > 配置组件的导入别名,例如 ~/components,这样你就可以通过 @/components/ui/button 而不是 ../../components/ui/button 来导入组件。

  • Configure import alias for utils?
    > 配置工具函数的导入别名,例如 ~/lib/utils

  • Are you using React Server Components? (yes / no)
    > 如果你使用 Next.js App Router,请选择 yes

完成这些步骤后,shadcn/ui 会自动完成以下工作:

  1. 在你的 package.json 中添加必要的依赖(如 tailwindcss-animate, class-variance-authority, lucide-react 等)。
  2. 更新你的 tailwind.config.js 文件,添加 shadcn/ui 需要的主题和插件配置。
  3. 创建一个 components.json 文件,用于记录你的 shadcn/ui 配置。
  4. 创建一个工具函数文件(例如 lib/utils.ts),其中包含一个 cn 函数,用于合并 Tailwind CSS 类名。

现在,你的项目就已经准备好使用 shadcn/ui 了。

二、添加和使用组件

1. 添加组件

shadcn/ui 的魅力在于按需添加。假设你需要一个按钮和一个卡片。

在终端中运行:

bash
npx shadcn-ui@latest add button card

这个命令执行后,你会发现你的 components 目录下多了两个文件:ui/button.tsxui/card.tsx

这就是 shadcn/ui 的核心——组件代码直接进入了你的项目。

2. 使用组件

现在,你可以在你的 React 组件中像使用本地组件一样使用它们:

“`tsx
// app/page.tsx

import { Button } from “@/components/ui/button”;
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from “@/components/ui/card”;

export default function HomePage() {
return (




Create project
Deploy your new project in one-click.

This is the card content area where you can add forms, text, or any other elements.








);
}
“`

上面的代码创建了一个简单的卡片,其中包含标题、描述、内容以及两个操作按钮。注意 Button 组件有一个 variant 属性,shadcn/ui 的组件通常都提供了类似的高度可定制的 props。

3. 定制组件

shadcn/ui 最强大的地方在于定制。

a. 通过类名定制

假设你想让 “Deploy” 按钮的背景色变为绿色。你不需要复杂的 API,直接在你的代码中添加 Tailwind CSS 类即可:

tsx
<Button className="bg-green-500 hover:bg-green-600">Deploy</Button>

b. 修改组件源代码

如果需要更深度的定制,比如给所有 Button 组件添加一个默认的 icon 位置。你可以直接打开 components/ui/button.tsx 文件进行修改。

原始的 button.tsx 可能看起来像这样:

“`tsx
// components/ui/button.tsx

import * as React from “react”
// … imports

const Button = React.forwardRef(
({ className, variant, size, asChild = false, …props }, ref) => {
const Comp = asChild ? Slot : “button”
return (

)
}
)
“`

你可以轻松地修改它,比如添加一个 leftIcon prop:

“`tsx
// components/ui/button.tsx (修改后)

export interface ButtonProps extends React.ButtonHTMLAttributes {
asChild?: boolean
leftIcon?: React.ReactNode; // 添加新的 prop
}

const Button = React.forwardRef(
({ className, variant, size, asChild = false, leftIcon, children, …props }, ref) => {
const Comp = asChild ? Slot : “button”
return (

{leftIcon && {leftIcon}} {/ 添加 icon 的渲染逻辑 /}
{children}

)
}
)
“`

现在,你项目中的所有 Button 组件都可以接受 leftIcon 这个 prop 了。这就是拥有代码所有权带来的灵活性。

三、高级技巧

1. 主题与深色模式

如果你在初始化时选择了使用 CSS 变量,那么实现深色模式会非常简单。

首先,安装 next-themes

bash
npm install next-themes

然后,创建一个 ThemeProvider

“`tsx
// components/theme-provider.tsx

“use client”

import * as React from “react”
import { ThemeProvider as NextThemesProvider } from “next-themes”
import { type ThemeProviderProps } from “next-themes/dist/types”

export function ThemeProvider({ children, …props }: ThemeProviderProps) {
return {children}
}
“`

在你的根布局(app/layout.tsx)中使用它:

“`tsx
// app/layout.tsx

import { ThemeProvider } from “@/components/theme-provider”

export default function RootLayout({ children }: { children: React.ReactNode }) {
return (



{children}



)
}
“`

最后,创建一个主题切换按钮:

“`tsx
// components/mode-toggle.tsx

“use client”

import * as React from “react”
import { Moon, Sun } from “lucide-react”
import { useTheme } from “next-themes”

import { Button } from “@/components/ui/button”

export function ModeToggle() {
const { theme, setTheme } = useTheme()

return (

)
}
“`

现在,你就可以在你的应用中自由切换浅色和深色模式了。shadcn/ui 的所有颜色都通过 CSS 变量定义,所以主题切换会无缝生效。

2. 构建复合组件

shadcn/ui 的组件设计哲学鼓励组合。你可以将基础组件组合成更复杂的、符合你业务需求的组件。

例如,你可以创建一个 PageHeader 组件,它由 h1 标签和一个 Button 组成:

“`tsx
// components/page-header.tsx

import { Button, ButtonProps } from “@/components/ui/button”;

interface PageHeaderProps {
title: string;
actionText?: string;
onActionClick?: () => void;
actionButtonProps?: ButtonProps;
}

export function PageHeader({ title, actionText, onActionClick, actionButtonProps }: PageHeaderProps) {
return (

{title}

{actionText && onActionClick && (

)}

);
}
“`

这样,你就在整个应用中有了一个统一的页面头部组件,并且它依然是完全可定制的。

结论

shadcn/ui 为 React 开发带来了新的范式。它通过将组件代码的所有权交还给开发者,解决了传统组件库的许多痛点。它让你在享受高质量、设计精良的组件基础的同时,又不失灵活性和控制力。

选择 shadcn/ui,意味着你选择了一种更现代、更可控、更贴近项目本身的方式来构建你的用户界面。如果你厌倦了与组件库的样式系统作斗争,希望能够更自由地创造,那么 shadcn/ui 绝对值得一试。

滚动至顶部