# Lesson 17.3: 设计系统搭建——从 Tokens 到组件封装

## 本课目标

- 理解 Design Tokens 的六大类别及其梯度设计逻辑
- 掌握 shadcn/ui + Tailwind 为什么适合 AI 驱动的产品开发
- 区分"看得见的"和"看不见的"组件，理解容器组件的重要性
- 学会 AI 友好的组件封装六原则，能指导 AI 生成一致的 UI

> **前置知识**：你已经了解了 WDS 的 8 阶段流水线（Lesson 17）和 108 个 UI 模式（Lesson 17.1）。本课深入 Phase 7（设计系统），教你如何从零搭建一套 AI 能理解和遵循的设计规范。

## 核心内容

### 为什么产品主理人要关心设计系统？

你可能会想："设计系统不是设计师和前端工程师的事吗？"

关键在于：**当你用 AI 生成页面时，AI 需要一套明确的规则来选择颜色、间距、组件。没有规范，AI 就会自由发挥——每次生成的风格都不一样。**

```
没有设计系统：AI 生成 5 个页面 → 5 种风格 → 产品像拼凑的
有设计系统：  AI 生成 5 个页面 → 同一套视觉语言 → 产品像一个人做的
```

设计系统就是你给 AI 的"视觉宪法"。

### Design Tokens：设计系统的原子

理想化的设计系统，是一套完全层级化的界面语言。通过层层嵌套，所有组件共享同一套样式逻辑。

**首先需要定义的是全局的基础变量（Design Tokens）**：

| 类别 | 包含什么 | 例子 |
|------|---------|------|
| 颜色 | 品牌色、功能色（成功/错误/警告/信息）、中性色、背景色、边框色、阴影色 | primary-500: #3b82f6 |
| 间距 | 间距的梯度，控制内外边距、元素间隔 | 4px, 8px, 12px, 16px, 24px, 32px, 48px |
| 圆角 | 圆角大小梯度 | 4px, 8px, 12px, 16px, 999px(全圆) |
| 阴影 | 投影类型（常规/内投影/投影）、投影大小 | shadow-sm, shadow-md, shadow-lg |
| 边框 | 粗细、样式 | 1px solid, 2px dashed |
| 文字 | 字距、行距、粗细、字体族、字号、行高 | text-sm: 14px/20px, text-base: 16px/24px |

**关键原则**：每个变量都提供若干种符合一定规律的**梯度变化**的样式选项。后续所有 UI 组件基于这些基础变量设计和开发，**不允许硬编码**。

```
❌ 硬编码：color: #3b82f6  （直接写死颜色值）
✅ Token：color: var(--primary-500)  （引用设计变量）
```

#### 统一样式逻辑的三个好处

1. **把控性更强**：所有页面元素都是由你定义的有限集合衍生而来，不会出现"意外"的样式
2. **方便扩展**：要扩大可选范围，只需基于一定规律增加梯度即可
3. **便于全局调整**：比如调整布局的宽松/紧凑程度，只需调整间距梯度，整体就一起变化

#### Tailwind 的默认主题

好消息是，你不需要从零定义所有 Token。Tailwind 已经预定义了一套主题，即使不自定义也有默认值可用。

Tailwind 默认主题覆盖的变量类别：

| 类别 | 说明 |
|------|------|
| 颜色 | 50-950 共 10 级色阶，覆盖所有常用色 |
| 间距 | 0-96 共 25 级梯度（0px 到 384px） |
| 圆角 | none 到 full 共 7 级 |
| 阴影 | sm 到 2xl 共 6 级 |
| 断点 | sm/md/lg/xl/2xl 用于响应式设计 |
| 容器宽度 | 控制最大内容宽度 |
| 模糊 | blur 系列用于毛玻璃效果 |
| 动画类型 | spin/ping/pulse/bounce 等 |
| 过渡曲线 | ease-in/out/linear 等 |

**自定义也很简单**：使用在线工具 [tweakcn](https://tweakcn.com)，通过滑块拖动调整各项参数，满意后直接复制主题代码——完全符合 Tailwind CSS 语法规范。

### 技术选型：为什么是 shadcn/ui + Tailwind？

市面上有很多 UI 框架，为什么作者选择了 shadcn/ui + Tailwind 的组合？

#### 技术方案对比

| 维度 | Ant Design / Chakra UI | shadcn/ui + Tailwind |
|------|----------------------|---------------------|
| 控制力 | 中等偏低（组件封装度高，改不动） | **高**（原子类+组件可拆可重构） |
| 组件丰富度 | 高（表单、表格、Modal 等齐全） | 中（基础组件为主，需手动组合） |
| 性能 | 一般（AntD 尤其偏重） | **优**（按需加载+原子 CSS，无冗余） |
| AI 友好度 | 低（黑盒封装，AI 不熟悉内部结构） | **高**（源码透明，LLM 训练数据中大量接触） |
| 适合场景 | 通用后台、表单驱动型 B 端项目 | 高定制要求、设计统一性强的现代 Web 项目 |

**核心原因**：shadcn/ui 的源码是开放的、结构清晰的、风格可编程的。对于利用大量 GitHub 项目训练的 LLM 来说，源码越透明，AI 理解和生成代码的准确度越高。

传统黑盒框架（Ant Design、Chakra UI）把组件封装得很深，AI 要么不知道怎么用，要么用法不规范。而 shadcn/ui 的组件就是普通 React 代码，AI 读得懂、改得了、不会搞出意料之外的结果。

### 组件分类：看得见的和看不见的

组件可以分为两大类：

#### 看得见的组件

这是大多数人理解的"组件"——基础的按钮、下拉框、输入框、列表等 UI 元素。

shadcn/ui 提供了这类基础组件，你可以在此基础上丰富变体并额外封装更多组件，扩展适用场景。

#### 看不见的组件

比较容易忽视的是"看不见的"部分——**页面级、模块级的各种容器**。这部分对于 AI 遵循规范来生成页面非常关键，决定了整体的视觉节奏。

一个典型的容器包括：

| 维度 | 决定了什么 |
|------|----------|
| **构成** | 包括哪些子元素 |
| **布局** | 子元素怎么分布、怎么对齐 |
| **尺寸** | 各部分占多大比例 |
| **间距** | 子元素之间的间隔 |
| **定位** | 固定/粘性/相对/绝对 |
| **滚动** | 内容装不下时怎么处理 |

这部分 shadcn/ui 里没有，灵活度较高，需要结合自己的项目来定义。

### 组件封装六原则

为了让 AI 能够严格遵循设计规范生成页面，组件封装应遵循以下原则：

#### 原则 1：少即是多

**不要无脑铺开，越少选择，AI 越容易选中。**

```
❌ 给 Button 定义 15 种变体 → AI 选择困难，经常选错
✅ 给 Button 定义 5 种变体 → AI 选对概率大幅提高
```

#### 原则 2：复用才封装

**具备复用性才封装，不具备复用性或会频繁调整的就不要封装。**

有些组件你还没想好要不要封装，但又觉得有必要统一的——先写成文档让 AI 参考（比如 layout 文档），等模式稳定后再封装。

#### 原则 3：面向演进

**基于未来一段时间的演进来抽象需要哪些组件，预留一定的包容性。**

- 太少 → 开发新功能时发现组件不够用
- 太多 → AI 选择困难，容易发散

找到平衡点：覆盖你未来 3-6 个月的使用场景。

#### 原则 4：便当优先

组件的变体包括两类：

| 类型 | 比喻 | 适用场景 |
|------|------|---------|
| **预设组合（便当）** | 搭配好的套餐，直接选 | 常见场景，优先使用 |
| **灵活勾选（自助餐）** | 自由组合参数 | 特殊场景，按需使用 |

**优先使用预设组合（便当），避免过于发散。**

```
// 便当式：预设好的变体
<Button variant="primary" />
<Button variant="destructive" />
<Button variant="outline" />

// 自助餐式：自由组合（慎用）
<Button color="blue" size="md" radius="lg" shadow="sm" border="1px solid" />
```

#### 原则 5：职责单一

**颗粒度适中，职责清晰。**

- 即使一个组件有很多变体，只要它们是同一个职责，就没问题
- 反之，如果一个组件变体很少但职责有跨越，AI 也可能找不到它

```
✅ Card 组件有 10 个变体，但都是"卡片展示"这个职责
❌ DataDisplay 组件只做 2 件事（展示列表和展示图表），职责不清晰
```

#### 原则 6：嵌套复用

**能嵌套就嵌套，避免重复造轮子。**

- 复杂组件里面包含基础组件（Card 里面包含 Button、Badge）
- 多个组件中具有相同的设计模式时，及时抽象出来

```
✅ ProductCard 内部使用通用的 Card + Button + Badge
❌ ProductCard 自己重新实现了卡片容器、按钮和徽标的逻辑
```

#### 总结：把 AI 想象成有血有肉的设计师

把 AI 想象成与你合作的设计师和前端工程师——道理是一样的：

- 选择越少，犯错越少
- 规则越明确，输出越一致
- 组件越可复用，效率越高

## 常见问题

**Q: 我不会写代码，能搭建设计系统吗？**

A: 可以。本课的核心是**理解设计决策**，而不是写代码。你可以用 `/bmad-wds-create-design-system` 命令让 AI 代理帮你生成整个设计系统。你只需要做出决策：用什么色系、间距是宽松还是紧凑、组件需要哪些变体。

**Q: shadcn/ui 组件太少了，不够用怎么办？**

A: shadcn/ui 的哲学是"基础够用，按需扩展"。你可以在其基础上：
1. 丰富已有组件的变体
2. 额外封装新组件（参考前面的六原则）
3. 从其他组件库借鉴设计模式，但用 shadcn/ui 的方式重新实现

**Q: Tailwind 的默认主题需要全部自定义吗？**

A: 不需要。建议只自定义**颜色**和**间距**这两个最关键的变量，其他保持默认值即可。颜色定义了产品的气质，间距定义了产品的节奏——这两个改了，整体感觉就完全不同。

**Q: tweakcn 是什么？怎么用？**

A: tweakcn 是一个在线的 Tailwind 主题定制工具。你可以在网页上通过滑块调整颜色、间距、圆角等参数，实时预览效果，满意后直接复制主题代码到项目中。对不会写 CSS 的产品主理人来说特别友好。

## 相关概念

- **WDS Phase 7: 设计系统**（Lesson 17）— 本课是 Phase 7 的深度展开
- **UI 设计词典**（Lesson 17.1）— 本课的组件封装基于 UI 模式词典中的模式
- **AI 原型实验室**（Lesson 17.2）— 原型中使用的样式应遵循设计系统的 Token 定义
- **前端模式**（相关技能）— shadcn/ui 和 Tailwind 的具体实现模式

## 下一步

请调用 `AskUserQuestion` 展示以下选项，让学习者点击选择；从每条中提炼 1-5 个词作为 label，其余写入 description，不要要求输入数字：

- 进入下一课：Lesson 17.4 - 排版美学——从网格极简到杂志之场
- 回顾 UI 模式：Lesson 17.1 - UI 设计词典
- 返回主菜单

---
*阶段 3 | Lesson 17.3/26 | 上一课: Lesson 17.2 - AI 原型实验室 | 下一课: Lesson 17.4 - 排版美学*
