设计创意

用 Codex 把假数据 UI 接成真页面:7 步覆盖五种状态

Codex 很容易用一组写死的数组做出“看起来已经完成”的 UI,真正接接口时却会同时出现字段为空、加载闪烁、错误无处恢复和权限判断散落等问题。本教程把任务拆成七步:先确认接口契约,再建立状态矩阵和数据适配层,最后用 Playwright 模拟响应并回到真实后端验证。目标不是生成一个演示页,而是交付一个在真实数据下仍然可用、可测试、可维护的页面。

Codex 真实数据 UI 的五态矩阵
先把 loading、empty、error、denied 与 success 写成验收对象,再开始实现。

适用场景

  • 设计稿或原型使用假数据,准备接 REST、GraphQL 或内部 API;
  • 现有页面只有 success 状态,真实网络下经常白屏、闪烁或显示错误占位;
  • 前后端字段命名、日期、金额与权限模型不一致,需要稳定适配;
  • 希望让 Codex 写实现,但不允许它猜业务规则或改动后端契约。

如果接口尚未确定、没有可访问的测试环境,先让后端提供 schema、示例响应和错误定义。Codex 可以帮助发现缺口,但不能替产品或后端决定字段语义。

第一步:让 Codex 审计仓库与接口契约,不要先写代码

把目标路由、现有组件、接口文档、一个脱敏的成功响应和常见错误响应交给 Codex。要求它只读检查调用链,并列出前端当前假设与后端事实的差异。Fetch 在 404 或 500 时通常不会自动 reject,因此还要明确哪些 HTTP 状态、业务码和网络异常分别如何处理。

先不要修改文件。阅读 AGENTS.md、目标页面、现有 API client、类型定义和测试。根据【接口文档链接或 schema】与脱敏响应,输出:
1. 页面当前依赖的字段;2. 字段类型、可空性和默认值;
3. HTTP 错误、业务错误与权限错误;4. 仍需产品或后端确认的问题。
不要发明字段,不要把 mock 数据当接口事实,不要输出任何凭证。

第二步:建立页面状态矩阵

先按用户能看到和能恢复的状态设计,而不是只按请求是否完成写一个布尔值。至少覆盖 loading、empty、error、denied 和 success;列表还应考虑 partial、分页失败与旧数据刷新。每个状态都要定义触发条件、界面文案、可用操作和测试证据。

状态 触发条件 界面与操作
loading 首次请求未完成 保持结构稳定,骨架不伪造真实内容
empty 请求成功且数据为零 说明原因,给出创建或调整筛选入口
error 网络、HTTP 或业务错误 保留上下文,提供重试与可理解错误
denied 身份有效但无权限 说明权限边界和申请方式,不只禁用按钮
success 数据可展示 处理缺省字段、长文本、刷新与分页
从 API 响应经过适配层生成 UI ViewModel
页面组件只消费稳定 ViewModel,接口字段变化集中在适配层处理。

第三步:用 adapter 把接口模型转换为 UI 模型

不要让卡片、表格和图表各自解析原始响应。先保留后端类型,再写一个纯函数把它转换成页面需要的 ViewModel;日期、金额、空值、枚举和权限都在这里显式处理。这样既减少组件内的条件分支,也方便用小样本做单元测试。

type ApiProject = {
  id: string;
  title: string | null;
  updated_at: string;
  budget_cents: number | null;
  permissions: { can_edit: boolean };
};

type ProjectCardVM = {
  id: string;
  title: string;
  updatedLabel: string;
  budgetLabel: string;
  canEdit: boolean;
};

export function toProjectCardVM(item: ApiProject): ProjectCardVM {
  return {
    id: item.id,
    title: item.title?.trim() || "未命名项目",
    updatedLabel: formatDate(item.updated_at),
    budgetLabel: item.budget_cents == null ? "未设置" : formatMoney(item.budget_cents),
    canEdit: item.permissions.can_edit,
  };
}

第四步:分别实现五种视觉状态

加载状态要尽量保持最终布局尺寸,避免内容出现时整体跳动;空状态不能复用错误图标;错误状态需要保留重试入口和必要的筛选上下文;成功状态也要验证缺省字段与长文本。权限状态则应区分“只读”和“完全不可见”,并由后端继续执行真正的权限校验。

请按已确认的状态矩阵实现目标页面。复用现有 EmptyState、ErrorState、Skeleton、Button 与 tokens;不要新增第二套基础组件。
- 首次加载:保留页面标题和筛选结构;
- 空数据:显示与当前筛选匹配的说明和下一步;
- 请求错误:显示可重试操作,不泄露服务端堆栈;
- 只读权限:内容可见、编辑入口替换为权限说明;
- 成功:处理 null、长标题、零值、分页和刷新。
完成后列出每个状态的触发方法和涉及文件。
给 Codex 的接口接入任务卡
高质量任务同时提供输入、边界和交付证据,而不是只说“把假数据换成接口”。

第五步:把任务写成“输入—边界—证据”

OpenAI 的前端与 Figma 转代码用例都强调先让 Codex 理解项目、复用已有设计系统,并通过实际检查迭代。一个可执行任务应包含接口与页面输入、不能动的边界,以及完成后必须提供的证据。

任务:把 /projects 的 mock 数据接入现有 GET /api/projects。
输入:接口 schema、成功/空/401/403/500 脱敏响应、目标路由、现有组件路径。
边界:不改接口字段;不新增 UI 框架;不输出凭证;不做无关重构;权限不能只靠前端隐藏。
交付:adapter 与类型;五种页面状态;单元测试;Playwright 网络模拟;lint、typecheck、test、build 结果;仍未确认的问题。
先给最小修改计划,确认现有模式后再改文件。

第六步:用 Playwright 模拟接口,而不是依赖不稳定测试数据

Playwright 官方的网络能力可以拦截并模拟响应。对每个状态建立独立测试,避免测试环境恰好有数据时永远覆盖不到 empty,也避免用真实 500 才能测试错误页。路由匹配要足够精确,并在真实后端验证前关闭 mock。

import { test, expect } from "@playwright/test";

test("projects empty state", async ({ page }) => {
  await page.route("**/api/projects?*", async route => {
    await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ items: [] }) });
  });
  await page.goto("/projects");
  await expect(page.getByRole("heading", { name: "还没有项目" })).toBeVisible();
  await expect(page.getByRole("button", { name: "创建项目" })).toBeEnabled();
});
Playwright 状态测试到真实后端复核的闭环
先稳定复现五类响应,再关闭 mock 检查真实接口、控制台和失败请求。

第七步:关闭 mock,回到真实后端做最终验证

模拟测试通过不等于接口已经接通。最后用测试账号访问真实环境,确认请求 URL、认证、缓存、分页、时区和错误结构;检查控制台、失败请求、重复请求、资源 404 与横向滚动。前端要显示安全、可理解的信息,服务端日志则保留可追踪的请求标识。

关闭所有 page.route mock,使用项目现有安全登录流程验证真实 /projects。记录:请求状态和响应结构、adapter 未覆盖字段、控制台错误、失败资源、重复请求、权限差异、390/768/1440px 布局。不要输出 token、cookie 或完整用户数据。只修与本任务有关的问题,并重新运行 unit、Playwright、lint、typecheck 和 build。

限制与常见误区

  • 前端 schema 校验只能更早发现异常,不能代替后端授权、数据校验和审计;
  • mock 响应必须来自真实接口契约并做脱敏,凭空编写的 mock 会制造虚假信心;
  • 同一个 HTTP 状态可能包含不同业务语义,错误文案与恢复动作需要产品和后端确认;
  • 乐观更新、离线缓存、流式响应和实时订阅需要额外状态,不能硬塞进简单五态模型;
  • 自动截图能发现视觉回归,但无法单独证明键盘顺序、可访问名称和真实数据正确。

总结

用 Codex 把假数据 UI 接成真页面,最重要的不是把 fetch 写得更快,而是把接口事实、页面状态和验收证据放在同一条链上。先审计契约,再用 adapter 稳定数据边界;先模拟每个状态,再关闭 mock 回到真实后端。这样交付的才不是一张会动的效果图,而是能面对真实网络、真实权限和真实数据的产品界面。


本文由「设计创意1984」整理编辑,转载请注明出处。

关注设计创意1984,持续获取设计趋势、AI创作方法与创意灵感。

设计创意1984网站二维码
设计创意1984微信公众号二维码


via:OpenAI Academy:Create frontend designs(OpenAI,官方)OpenAI Academy:Turn Figma designs into code(OpenAI,官方)Figma:How to move fast toward the right thing(Jake Albaugh)Playwright:Network(官方文档)MDN:Using the Fetch API(Mozilla Contributors)

()

本文由 设计创意1984 作者:admin 发表,转载请注明来源!

热评文章

发表回复