跳转至

02 UI 设计与设计稿转代码:Figma MCP 实战

目标:把需求变成 人能评审的视觉稿,再变成 AI 能精确还原的设计 token 和组件规格。设计不是“画得好看”,而是“把交互、状态和边界画清楚”。


1. 这个阶段要产出什么

产物 路径 作用
设计系统 Figma 文件 / docs/02-ui/design-tokens.json 颜色、字体、间距、圆角、阴影
页面设计稿 Figma frames / docs/02-ui/screens/ 每个页面的正常态与异常态
UI 规格说明 docs/02-ui/ui-spec.md 页面、组件、状态、交互、响应式规则
设计走查记录 docs/02-ui/design-review.md 发现的问题与修正
前端原型任务 docs/02-ui/frontend-brief.md 交给前端 Agent 的实现说明

关键原则:设计稿不是“参考图”,而是“契约”。如果设计稿没有定义空状态、加载态、错误态,前端 Agent 就会自己发明,最后验收时你说不清是谁的错。


2. Figma MCP:它能做什么,不能做什么

2.1 三种能力要分清

能力 说明 可靠性
读取设计 获取选中 frame 的结构、样式、变量、图片、代码片段 高(官方 MCP 支持)
生成代码 根据选中设计生成 HTML/CSS/React/Vue 片段 中(需要人工调整)
修改设计 在 Figma 中创建/修改图层、组件、变量 低-中(官方 MCP 通常不直接写入;需插件/第三方)

重要认知:

  • 官方 Figma Dev Mode MCP Server 主要面向“设计 → 代码”的读取和检查,不是完整的“AI 自动做设计”工具。
  • 如果你的目标是“让 AI 按需求生成/改动设计稿”,通常有三条路:
  • Figma Plugin API:写一个本地插件,让 AI 生成插件代码,插件在 Figma 中创建/修改图层。
  • 第三方 Figma MCP:部分社区 MCP 提供写入能力,但稳定性和权限模型要自己验证。
  • HTML/CSS 原型即设计源:先用 AI 生成高保真 HTML 原型,人评审后再反向整理成 Figma 组件,或直接把 HTML 作为设计契约。
  • 本教程推荐:读取用官方 MCP,写入用插件或 HTML 原型。不要假设一个 MCP 能完成所有事。

2.2 官方 Figma Dev Mode MCP 安装

前提:

  • Figma 桌面应用(不是浏览器版)。
  • Figma 付费计划中的 Dev 或 Full seat(官方限制,具体以 Figma 当前政策为准)。
  • 打开一个 Design 文件,进入 Dev Mode(Shift + D)。

步骤:

  1. 在右侧 Inspect 面板找到 MCP server,点击 Enable desktop MCP server。
  2. 服务默认监听 http://127.0.0.1:3845/mcp。
  3. 在终端注册到 Claude Code:
claude mcp add --transport http figma-dev-mode-mcp-server http://127.0.0.1:3845/mcp

如果当前版本使用 SSE:

claude mcp add --transport sse figma-dev-mode-mcp-server http://127.0.0.1:3845/sse
  1. 验证:
claude mcp list

或在 Claude Code 中输入 /mcp,确认 figma-dev-mode-mcp-server 已连接。

  1. 在 Figma 中选中一个 frame 或组件,然后在 Claude Code 中引用它:
请读取我在 Figma 中选中的 frame,输出:
1. 图层结构(从外到内,最多 4 层)
2. 使用的颜色、字体、间距、圆角变量
3. 组件的所有状态(default/hover/active/disabled/loading/error)
4. 生成对应的 HTML + CSS(使用 CSS 变量)
不要猜测未选中的内容。

2.3 备选:社区 Figma MCP

社区方案通常通过 Figma REST API 读取文件,需要 Personal Access Token:

# 示例:具体包名和参数以项目 README 为准
claude mcp add figma -- \
  npx -y figma-developer-mcp --figma-api-key=<YOUR_FIGMA_TOKEN> --stdio

注意:

  • Token 不要写进仓库,放在环境变量或 ~/.claude/settings.json 的私有配置中。
  • 社区 MCP 的能力、稳定性和安全性由你自行评估。
  • 读取整个文件可能非常耗 token,务必只读选中的 frame/node。

2.4 如果 MCP 不可用

不要让工具阻塞流程。降级方案:

  1. 导出设计图:Figma 导出 PNG/SVG 到 docs/02-ui/screens/。
  2. 导出设计 token:Figma Variables 导出 JSON,或手工整理成 design-tokens.json。
  3. 让 AI 看图和读 token:用识图能力(如 GLM-4V 等)描述设计,再生成 HTML/CSS。
  4. 以 HTML 原型为准:先做高保真 HTML,评审通过后再补 Figma。

3. 先建设计系统,再画页面

3.1 为什么先做 token

如果每个页面都让 AI “自由发挥”,你会得到 12 种蓝色、7 种圆角、5 种阴影。设计系统的作用是把这些决策 提前固化,让 AI 在约束内生成。

3.2 最小设计系统

{
  "color": {
    "brand-50": "#eff6ff",
    "brand-100": "#dbeafe",
    "brand-500": "#3b82f6",
    "brand-600": "#2563eb",
    "brand-700": "#1d4ed8",
    "neutral-0": "#ffffff",
    "neutral-50": "#f8fafc",
    "neutral-100": "#f1f5f9",
    "neutral-300": "#cbd5e1",
    "neutral-500": "#64748b",
    "neutral-700": "#334155",
    "neutral-900": "#0f172a",
    "success-500": "#22c55e",
    "warning-500": "#f59e0b",
    "danger-500": "#ef4444",
    "info-500": "#0ea5e9"
  },
  "font": {
    "family-sans": "Inter, 'Noto Sans SC', system-ui, sans-serif",
    "family-mono": "'JetBrains Mono', monospace",
    "size-xs": "12px",
    "size-sm": "14px",
    "size-md": "16px",
    "size-lg": "18px",
    "size-xl": "24px",
    "size-2xl": "32px",
    "weight-regular": 400,
    "weight-medium": 500,
    "weight-semibold": 600,
    "weight-bold": 700
  },
  "space": {
    "1": "4px",
    "2": "8px",
    "3": "12px",
    "4": "16px",
    "6": "24px",
    "8": "32px",
    "12": "48px",
    "16": "64px"
  },
  "radius": {
    "sm": "6px",
    "md": "10px",
    "lg": "16px",
    "full": "9999px"
  },
  "shadow": {
    "sm": "0 1px 2px rgba(15,23,42,0.06)",
    "md": "0 4px 12px rgba(15,23,42,0.08)",
    "lg": "0 12px 32px rgba(15,23,42,0.12)"
  }
}

落地到 CSS:

:root {
  --color-brand-500: #3b82f6;
  --color-brand-600: #2563eb;
  --color-neutral-0: #ffffff;
  --color-neutral-900: #0f172a;
  --font-sans: Inter, "Noto Sans SC", system-ui, sans-serif;
  --space-4: 16px;
  --radius-md: 10px;
  --shadow-md: 0 4px 12px rgba(15, 23, 42, 0.08);
}

规则:前端代码里不允许出现魔法色值和魔法间距。 所有值必须来自 token。代码审查时可以直接 rg "#[0-9a-fA-F]{3,6}" frontend/src 检查。

3.3 组件清单

在画页面前,先列组件:

组件 变体/状态 说明
Button primary/secondary/ghost/danger;default/hover/active/disabled/loading 尺寸 sm/md/lg
Input default/focus/error/disabled;带前缀/后缀 支持 helper text
Select default/open/disabled/error 支持搜索
Modal default/confirm/danger 支持 esc 关闭
Toast success/error/warning/info 自动消失
Table default/loading/empty/error 支持排序、分页
Tabs default/active/disabled
Avatar image/initials/fallback
Badge neutral/brand/success/warning/danger
EmptyState default/error/no-permission 必须有插画/文案/动作
Skeleton text/card/table 加载态
Pagination default/disabled

每个组件必须定义状态。 没有状态定义的组件,前端 Agent 会自己编,最后交互不一致。


4. 从需求到设计稿

4.1 先生成页面清单

让 AI 从 spec.md 和 user-story.csv 推导页面:

你是资深 UI/UX 设计师。请阅读:
- @docs/00-discovery/spec.md
- @docs/00-discovery/user-story.csv
- @docs/02-ui/design-tokens.json

请输出页面清单,格式:
| 页面 ID | 页面名称 | 路由 | 对应故事 | 主要组件 | 需要的状态 |
状态至少包括:默认、加载、空、错误、无权限、成功反馈。
不要画图,只输出清单和每个页面的信息架构。

示例输出:

页面 ID 页面名称 路由 对应故事 主要组件 状态
P-001 登录页 /login US-001 Form, Input, Button, Alert 默认/提交中/错误/锁定
P-002 项目列表 /projects US-002 Card, EmptyState, Skeleton 默认/加载/空/错误
P-003 项目详情/看板 /projects/:id US-004, US-005 Kanban, TaskCard, Modal 默认/加载/空/错误/无权限
P-004 成员管理 /projects/:id/members US-003 Table, InviteModal 默认/加载/空/错误
P-005 任务详情 /projects/:id/tasks/:taskId US-004 Drawer, Form, CommentList 默认/加载/错误/无权限

4.2 线框图(Wireframe)提示词

先低保证速度,再高保真:

请为 P-003 项目看板设计线框图(低保真)。

要求:
- 使用 1440x900 桌面端画布。
- 顶部:项目名、成员头像组、筛选、设置。
- 主体:三列看板(待办/进行中/已完成),每列有标题和任务数量。
- 任务卡片:标题、负责人头像、截止日期、优先级标记。
- 右下角:新建任务浮动按钮。
- 必须画出:加载态、空状态、错误态。
- 不要使用真实品牌色,先用灰度。
输出:每个区块的尺寸、间距、层级关系,以及交互说明。

4.3 高保真提示词

请把 P-003 线框图升级为高保真设计。

约束:
- 严格使用 @docs/02-ui/design-tokens.json 中的颜色、字体、间距、圆角、阴影。
- 桌面端 1440px,平板 1024px,移动端 390px 三个断点。
- 看板列宽 320px,列间距 16px,卡片间距 12px。
- 任务卡片 hover 时阴影从 sm 变为 md,过渡 150ms。
- 优先级用 Badge:高=danger,中=warning,低=neutral。
- 截止日期过期显示 danger 色,并加“已逾期”标签。
- 空状态:插画 + “还没有任务” + “新建任务”按钮。
- 加载态:3 张骨架卡片。
- 错误态:错误图标 + “加载失败” + “重试”按钮。
- 所有可点击元素有 focus ring,对比度符合 WCAG AA。
输出:设计说明 + 组件清单 + 需要新增的 token(如果有)。

4.4 设计稿的命名规范

Figma 图层命名混乱,是 AI 读取失败的主要原因。建议:

Page/Projects
  Frame/Projects-Desktop-1440
    Section/Header
      Component/Logo
      Component/SearchInput
      Component/AvatarGroup
    Section/Content
      Component/ProjectCard (x6)
      Component/EmptyState
    Section/Footer
  Frame/Projects-Tablet-1024
  Frame/Projects-Mobile-390
  Frame/Projects-States
    Component/Skeleton
    Component/ErrorState
    Component/NoPermissionState

规则:

  • 用 / 表达层级,用 - 表达变体。
  • 组件用 Component/ 前缀。
  • 状态单独放一个 frame,不要藏在图层里。
  • 不要用 Frame 123、Rectangle 45 这种默认名。
  • 设计稿和 ui-spec.md 的页面 ID 一一对应。

5. 设计评审:人要看什么

AI 可以生成很多稿,但审美和产品判断必须由人做。评审时按以下清单走:

5.1 信息架构

  • 用户第一眼能看到最重要的信息吗?
  • 主操作按钮是否明显?次操作是否弱化?
  • 导航层级是否清晰?用户知道自己在哪吗?
  • 页面之间的跳转是否符合直觉?

5.2 视觉一致性

  • 颜色、字体、间距是否来自 token?
  • 相同组件在不同页面是否一致?
  • 圆角、阴影、边框是否统一?
  • 图标风格是否一致?线宽、尺寸是否统一?

5.3 状态完整性

  • 默认态、hover、active、focus、disabled 都有吗?
  • 加载态、空状态、错误态、无权限态都有吗?
  • 表单校验错误如何展示?错误信息是否具体?
  • 成功操作有反馈吗?失败操作能恢复吗?

5.4 可用性与可访问性

  • 对比度是否达到 WCAG AA(正文 4.5:1,大字 3:1)?
  • 关键流程能否只用键盘完成?
  • 触控目标是否至少 44x44px?
  • 是否只靠颜色传达信息?(色盲用户)
  • 文案是否清晰、无歧义、无术语堆砌?

5.5 响应式

  • 1440 / 1024 / 390 三个断点都设计了吗?
  • 表格在窄屏如何降级?卡片?横向滚动?
  • 看板在移动端是横向滚动还是单列?
  • 弹窗在移动端是全屏还是底部抽屉?

5.6 边界与异常

  • 超长标题如何截断?tooltip 还是换行?
  • 没有数据时显示什么?
  • 网络慢时显示什么?
  • 没有权限时显示什么?
  • 数据量大时如何分页/虚拟滚动?

评审结论写入 docs/02-ui/design-review.md:

# 设计评审记录

日期:2026-10-28
评审人:xxx

## 结论
有条件通过。需修正 3 个问题后再进入前端开发。

## 问题
| ID | 页面 | 问题 | 严重度 | 处理 |
|---|---|---|---|---|
| D-001 | P-003 | 看板在 390px 下三列挤压,不可用 | 高 | 改为单列 + 横向滑动切换 |
| D-002 | P-001 | 错误提示只靠红色,色盲不可辨 | 中 | 增加图标和文案 |
| D-003 | P-004 | 邀请弹窗缺少“成员已存在”状态 | 中 | 补充状态设计 |

6. 设计稿转代码:从 Figma 到前端

6.1 推荐流程

Figma 选中 frame
  ↓
MCP 读取结构、样式、变量
  ↓
输出 design-spec(组件树 + token + 状态)
  ↓
AI 生成 HTML/CSS(静态原型)
  ↓
截图/浏览器检查
  ↓
人评审视觉
  ↓
转 Vue 组件
  ↓
接 API

不要一步从 Figma 跳到完整 Vue 应用。 先把静态视觉做对,再叠加状态和接口,返工成本最低。

6.2 让 MCP 输出“可执行规格”

请读取我在 Figma 中选中的 P-003 看板 frame。

输出严格按以下结构,不要省略:
1. 页面结构树(最多 4 层,标注每个节点的角色)
2. 布局参数(flex/grid、宽高、间距、对齐)
3. 使用的 token(颜色/字体/间距/圆角/阴影)
4. 组件实例及变体
5. 状态清单(默认/加载/空/错误/无权限)
6. 响应式规则(1440/1024/390)
7. 交互说明(hover/focus/点击/拖拽)
8. 不确定的地方(列出,不要猜)

然后生成 HTML + CSS,要求:
- 使用语义化标签
- 使用 CSS 变量,值来自上面的 token
- 不使用任何 UI 框架
- 不写 JavaScript,只做静态视觉
- 图片用占位符,标注尺寸
- 输出完整可运行的单文件 HTML

6.3 视觉比对

生成后,用 Chrome MCP 打开原型,截图,和设计稿对比:

请用 Chrome MCP 打开 http://localhost:5173/projects/demo,
截取 1440x900 的整页截图,保存到 docs/02-ui/screens/impl-p003.png。
然后用 chrome_javascript 读取以下元素的 computed style:
- 看板容器:display, gap, padding
- 任务卡片:width, border-radius, box-shadow
- 标题:font-size, font-weight, line-height, color
把结果和 @docs/02-ui/design-tokens.json 对比,列出偏差。
不要读取截图内容,只保存文件。

注意:这里截图是给人看的证据,不是给模型看的输入。让模型用 chrome_javascript 读 computed style,比让它“看截图猜像素”准确得多。

6.4 设计到代码的映射表

让 AI 维护一份映射,方便后续组件复用:

设计组件 前端组件 文件 状态
Button/primary/md <AppButton variant="primary" size="md"> components/ui/AppButton.vue 已实现
Input/error <AppInput :error="..."> components/ui/AppInput.vue 已实现
TaskCard <TaskCard> components/task/TaskCard.vue 待实现
Kanban/Column <KanbanColumn> components/kanban/KanbanColumn.vue 待实现
EmptyState <EmptyState> components/ui/EmptyState.vue 待实现

7. ui-spec.md:前端 Agent 的实现契约

设计稿是视觉,ui-spec.md 是行为。它的结构:

# UI 规格说明

## 1. 设计 token
(引用 design-tokens.json)

## 2. 页面清单
| 页面 ID | 名称 | 路由 | 故事 | 设计稿 | 状态 |
|---|---|---|---|---|---|
| P-001 | 登录 | /login | US-001 | screens/p001.png | 默认/提交中/错误/锁定 |

## 3. 全局布局
- 顶部导航:高度 64px,固定,阴影 sm
- 侧边栏:宽度 240px,可折叠
- 内容区:最大宽度 1280px,左右 padding 32px
- 移动端:侧边栏变为抽屉,底部导航

## 4. 组件规格
### AppButton
- 变体:primary / secondary / ghost / danger
- 尺寸:sm (32px) / md (40px) / lg (48px)
- 状态:default / hover / active / disabled / loading
- loading 时禁用点击,显示 spinner,保留原宽度

## 5. 页面规格
### P-003 项目看板
- 数据来源:`GET /api/v1/projects/{id}`、`GET /api/v1/tasks?project_id=...`
- 加载态:3 列骨架
- 空状态:EmptyState + 新建任务按钮
- 错误态:错误提示 + 重试
- 无权限:NoPermission 页面,不显示数据
- 拖拽:调用 `PATCH /api/v1/tasks/{id}/status`,乐观更新,失败回滚

## 6. 响应式
| 断点 | 布局 |
|---|---|
| ≥1280 | 三列看板 + 侧边栏 |
| 768-1279 | 三列看板 + 折叠侧边栏 |
| <768 | 单列看板 + 底部导航 + 横向切换 |

## 7. 可访问性
- 所有图标按钮有 aria-label
- 表单错误用 aria-describedby 关联
- 弹窗打开时焦点锁定,Esc 关闭
- 颜色对比度 ≥ 4.5:1

## 8. 文案
(所有用户可见文案集中列出,方便国际化)

## 9. 未决问题
- 拖拽在移动端是否需要?
- 看板列是否允许自定义?

8. 设计阶段的 AI 提示词模板

8.1 设计系统生成

你是设计系统专家。请基于以下产品气质生成一套设计 token:
- 产品:团队任务协作工具
- 气质:专业、清爽、高效、不过度装饰
- 用户:20-50 人的咨询/创意团队
- 需要支持浅色模式(深色模式可选)

输出:
1. 颜色(品牌色 50-900、中性色 0-900、语义色 success/warning/danger/info)
2. 字体(family、字号、字重、行高)
3. 间距(4px 基准)
4. 圆角、阴影
5. 使用规则(什么时候用哪个层级)
6. 对比度检查(正文/按钮/链接)
输出 JSON + CSS 变量两版。

8.2 页面设计

你是资深 UI 设计师。请设计 P-003 项目看板。

输入:
- 需求:@docs/00-discovery/user-story-details.md#us-004
- token:@docs/02-ui/design-tokens.json
- 组件清单:@docs/02-ui/ui-spec.md#组件规格

输出:
1. 信息架构(区块、层级、优先级)
2. 桌面/平板/移动三套布局
3. 正常态、加载态、空状态、错误态、无权限态
4. 交互说明(hover/focus/点击/拖拽)
5. 可访问性说明
6. 需要新增的组件或 token
不要输出代码。

8.3 设计批判

你是苛刻的设计评审专家。请审查 @docs/02-ui/screens/p003.png 和 @docs/02-ui/ui-spec.md。

找出:
1. 信息层级不清的地方
2. 视觉不一致(颜色/间距/圆角/阴影)
3. 缺失的状态
4. 可访问性问题(对比度、键盘、触控目标)
5. 响应式问题
6. 文案问题
7. 过度设计或无关装饰
输出表格:问题、位置、严重度、建议。
不要改文件。

9. 常见问题与处理

问题 1:Figma MCP 连不上

排查顺序:

  1. Figma 是桌面应用吗?浏览器版不支持本地 MCP。
  2. 是否在 Dev Mode?Shift + D。
  3. MCP server 是否已 Enable?
  4. 端口 3845 是否被占用?lsof -i :3845 / ss -lntp | grep 3845。
  5. 传输方式选对了吗?先试 http,再试 sse。
  6. 公司网络/代理是否拦截 localhost?尝试 NO_PROXY=127.0.0.1,localhost。
  7. Claude Code 中 /mcp 是否显示 connected?

问题 2:AI 生成的设计“很通用”

原因:约束太少,AI 会回退到训练数据里的常见模板。

修正:

  • 提供明确的品牌气质、参考产品、反例;
  • 提供 token 和组件库;
  • 要求先出 3 个方向,人选一个再深化;
  • 明确“不要做什么”(不要渐变、不要玻璃拟态、不要过多阴影)。

问题 3:设计稿转代码后“差一点”

常见原因:

  • 设计稿用了非 token 的魔法值;
  • 字体未加载,fallback 字体导致行高变化;
  • 间距用了 margin 叠加而不是 gap;
  • 响应式断点没对齐;
  • 图标尺寸/线宽不一致。

修正:

  • 强制 token;
  • 在 index.html 中预加载字体;
  • 用 flex/grid 的 gap,避免 margin 折叠;
  • 用同一个断点变量;
  • 用 SVG 组件,统一 currentColor。

问题 4:设计稿没有异常状态

这是 AI 设计的通病。修正:在提示词中强制列出状态清单,并在评审时逐项检查。没有状态设计,不允许进入前端开发。

问题 5:AI 直接生成 Vue,视觉和逻辑混在一起

修正:强制两阶段:

  1. 静态 HTML/CSS,只做视觉;
  2. 人评审通过后,再拆 Vue 组件、接 API。

10. G2 设计门禁

在进入前端开发前,人需要确认:

  • 每个 P0/P1 页面都有设计稿或明确原型
  • 设计 token 已固化,前端可以直接引用
  • 组件清单和状态清单完整
  • 空/加载/错误/无权限状态都有设计
  • 响应式规则明确
  • 可访问性基本达标
  • 设计评审问题已修复或有明确处理计划
  • ui-spec.md 已更新
  • 人明确说“这个视觉方向我接受”

下一章:03 前端开发 —— 从静态原型到 Vue SPA,把设计变成可交互的产品。