Glittering's blog Glittering's blog
Home
  • 学习手册

    • 《JavaScript教程》
    • 《TypeScript教程》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • 《React18》
    • 《CSS》
    • 《Tailwind CSS》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)

Glitz Ma

前端开发工程师
Home
  • 学习手册

    • 《JavaScript教程》
    • 《TypeScript教程》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • 《React18》
    • 《CSS》
    • 《Tailwind CSS》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)
  • CSS

    • CSS教程和技巧收藏
    • css块元素和行内元素
    • 盒子模型
    • BFC和IFC
    • 字体font-weight相关知识
    • CSS-function汇总
    • CSS3之has函数的使用
    • CSS3之transition过渡
    • CSS3之animation动画
    • css动画性能优化
    • flex布局语法
    • flex布局案例
    • Grid布局语法
    • flex布局和grid布局的区别
    • 「布局技巧」图片未加载前自动撑开元素高度
    • shadcn/ui学习笔记
      • 一、shadcn/ui 是什么?
      • 二、核心技术栈
      • 三、安装与初始化(核心流程)
      • 四、组件是怎么来的?
      • 五、CVA(核心重点)
        • 1️⃣ 为什么不用一堆 className?
        • 2️⃣ CVA 原理
      • 六、Radix UI 的作用
      • 七、主题系统(CSS Variables)
      • 八、常用目录结构
      • 九、使用范式(很重要)
        • 1️⃣ 组合而不是继承
        • 2️⃣ 不要改 UI 组件逻辑
      • 十、适合什么项目?
      • 十一、你学到什么程度算“会了”?
      • 十二、学习路径建议(给你一个进阶路线)
    • shadcn/ui CVA 是什么
    • shadcn/ui radix ui 讲解
    • h5适配方案
    • 前端1px的几种实现方案
    • 文字在一行或多行时超出显示省略号
    • 水平垂直居中的几种方式-案例
    • 如何根据系统主题自动响应CSS深色模式
    • 工作中遇到的css问题记录
    • 今天总结一下用到的css吧
  • 页面
  • CSS
mamingjuan
2025-04-18
目录

shadcn/ui学习笔记

shadcn/ui(常被口头叫 shad/ui)基础知识速览,偏向前端工程实战,适合已经会 React + Tailwind 的开发者快速上手。


# 一、shadcn/ui 是什么?

shadcn/ui ≠ 组件库

它是一个 组件源码集合 + CLI 工具

核心特点:

  • ✅ 不是 npm 安装的黑盒组件
  • ✅ 组件代码直接复制到你项目中
  • ✅ 基于 Radix UI(无样式、可访问性强)
  • ✅ 使用 Tailwind CSS 写样式
  • ✅ 高度可定制、可维护

一句话:

你拥有组件,而不是依赖组件库


# 二、核心技术栈

技术 作用
React 组件系统
Radix UI 无障碍交互逻辑(Dialog / Dropdown / Popover 等)
Tailwind CSS 样式系统
class-variance-authority(CVA) 组件变体管理
lucide-react 默认图标
clsx + tailwind-merge className 合并

# 三、安装与初始化(核心流程)

npx shadcn@latest init
1

会做的事:

  1. 检测你是否有 Tailwind

  2. 生成配置文件 components.json

  3. 创建目录:

    components/
      ui/
    lib/
      utils.ts
    
    1
    2
    3
    4

# 四、组件是怎么来的?

npx shadcn@latest add button
1

结果:

components/ui/button.tsx
1

👉 源码直接进你项目

// components/ui/button.tsx
const buttonVariants = cva(
  "inline-flex items-center justify-center rounded-md text-sm font-medium",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground",
        outline: "border border-input bg-background",
      },
      size: {
        sm: "h-9 px-3",
        lg: "h-11 px-8",
      },
    },
    defaultVariants: {
      variant: "default",
      size: "sm",
    },
  }
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 五、CVA(核心重点)

shadcn/ui 的灵魂

# 1️⃣ 为什么不用一堆 className?

❌ 坏方式:

<button className={`
  px-4 py-2
  ${primary && "bg-blue-500"}
  ${size === "lg" && "text-lg"}
`} />
1
2
3
4
5

✅ shadcn/ui:

<Button variant="outline" size="lg" />
1

# 2️⃣ CVA 原理

const buttonVariants = cva(
  "inline-flex items-center justify-center rounded-md font-medium",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground",
        outline: "border border-input",
        ghost: "hover:bg-accent",
      },
      size: {
        sm: "h-9 px-3",
        md: "h-10 px-4",
        lg: "h-11 px-8",
      },
    },
    defaultVariants: {
      variant: "default",
      size: "md",
    },
  }
)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

最终:

buttonVariants({ variant: "outline", size: "lg" })
1

# 六、Radix UI 的作用

Radix 提供的是:

  • 键盘可访问性
  • 焦点管理
  • ARIA
  • 行为逻辑

比如 Dialog:

<Dialog>
  <DialogTrigger>Open</DialogTrigger>
  <DialogContent>
    <DialogHeader>
      <DialogTitle>Title</DialogTitle>
    </DialogHeader>
  </DialogContent>
</Dialog>
1
2
3
4
5
6
7
8

shadcn/ui 做的事:

  • 给 Radix 组件 套 Tailwind 样式
  • 统一 API 风格

# 七、主题系统(CSS Variables)

shadcn/ui 不写死颜色

:root {
  --primary: 222.2 47.4% 11.2%;
  --primary-foreground: 210 40% 98%;
}
1
2
3
4

使用时:

bg-primary text-primary-foreground
1

优势:

  • 🌗 深色模式天然支持
  • 🎨 主题切换成本极低

# 八、常用目录结构

components/
  ui/
    button.tsx
    dialog.tsx
    dropdown-menu.tsx
lib/
  utils.ts   // cn() 工具函数
1
2
3
4
5
6
7

utils.ts:

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}
1
2
3

# 九、使用范式(很重要)

# 1️⃣ 组合而不是继承

<Button asChild>
  <Link href="/login">Login</Link>
</Button>
1
2
3

asChild 基于 Radix Slot


# 2️⃣ 不要改 UI 组件逻辑

❌

components/ui/button.tsx
1

✅

components/common/submit-button.tsx
1

# 十、适合什么项目?

  • ✅ 中大型 React / Next.js 项目
  • ✅ 设计系统 / Design System
  • ❌ 不适合“装完就用”的新手项目

# 十一、你学到什么程度算“会了”?

你能做到:

  • 看懂 shadcn/ui 组件源码
  • 自己写一个带 CVA 的组件
  • 基于 Radix 封装业务组件
  • 定制主题而不是改 class

# 十二、学习路径建议(给你一个进阶路线)

  1. 熟悉 Button / Input / Dialog 源码
  2. 学会 CVA
  3. 深入 Radix(Dialog / Popover / Dropdown)
  4. 自己封装一个组件(如:DataTable)
  5. 设计一套主题变量
上次更新: 2026/01/07, 09:20:46
「布局技巧」图片未加载前自动撑开元素高度
shadcn/ui CVA 是什么

← 「布局技巧」图片未加载前自动撑开元素高度 shadcn/ui CVA 是什么→

Copyright © 2015-2026 Glitz Ma
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式