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)。
步骤:
- 在右侧 Inspect 面板找到 MCP server,点击 Enable desktop MCP server。
- 服务默认监听
http://127.0.0.1:3845/mcp。 - 在终端注册到 Claude Code:
如果当前版本使用 SSE:
- 验证:
或在 Claude Code 中输入 /mcp,确认 figma-dev-mode-mcp-server 已连接。
- 在 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 不可用¶
不要让工具阻塞流程。降级方案:
- 导出设计图:Figma 导出 PNG/SVG 到
docs/02-ui/screens/。 - 导出设计 token:Figma Variables 导出 JSON,或手工整理成
design-tokens.json。 - 让 AI 看图和读 token:用识图能力(如 GLM-4V 等)描述设计,再生成 HTML/CSS。
- 以 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 连不上¶
排查顺序:
- Figma 是桌面应用吗?浏览器版不支持本地 MCP。
- 是否在 Dev Mode?
Shift + D。 - MCP server 是否已 Enable?
- 端口 3845 是否被占用?
lsof -i :3845/ss -lntp | grep 3845。 - 传输方式选对了吗?先试
http,再试sse。 - 公司网络/代理是否拦截 localhost?尝试
NO_PROXY=127.0.0.1,localhost。 - 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,视觉和逻辑混在一起¶
修正:强制两阶段:
- 静态 HTML/CSS,只做视觉;
- 人评审通过后,再拆 Vue 组件、接 API。
10. G2 设计门禁¶
在进入前端开发前,人需要确认:
- 每个 P0/P1 页面都有设计稿或明确原型
- 设计 token 已固化,前端可以直接引用
- 组件清单和状态清单完整
- 空/加载/错误/无权限状态都有设计
- 响应式规则明确
- 可访问性基本达标
- 设计评审问题已修复或有明确处理计划
-
ui-spec.md已更新 - 人明确说“这个视觉方向我接受”
下一章:03 前端开发 —— 从静态原型到 Vue SPA,把设计变成可交互的产品。