Eazo 生成的页面能直接用、数据与接口部分通常要自己补

文章导读
Eazo 生成的页面里,展示层通常能直接用:布局、样式、响应式、通用组件和交互骨架大多可以留;数据层与请求层通常要自己补:写死的示例数组、模拟请求、接口地址、字段命名和错误处理,基本都要按自有后端重写。判断一个文件该留还是该改,先看它是否只依赖 props 或静态内容,而不是看它长得是否完整。
📋 目录
  1. 壹 沿页面文件确认哪些组件可以直接留用
  2. 贰 找出数据来源被写死的位置
  3. 叁 把请求逻辑单独抽成一层便于替换地址
  4. 肆 用一条自有数据走通列表到详情的链路
  5. 伍 把仍依赖生成假设的部分标注出来
A A

Eazo 生成的页面里,展示层通常能直接用:布局、样式、响应式、通用组件和交互骨架大多可以留;数据层与请求层通常要自己补:写死的示例数组、模拟请求、接口地址、字段命名和错误处理,基本都要按自有后端重写。判断一个文件该留还是该改,先看它是否只依赖 props 或静态内容,而不是看它长得是否完整。

适用场景:用 Eazo 生成页面后准备接自有后端。操作动作:按文件把展示层与数据层分开,保留纯展示组件,把写死数据、请求地址、字段映射逐处登记后重写。验证方式:用一条真实数据从列表点进详情,在 Network 面板确认请求 URL 与响应,页面不出现 undefined。风险边界:鉴权方式、分页约定、枚举值含义无法从生成代码推断时不要猜,需与接口方确认后再定。

沿页面文件确认哪些组件可以直接留用

生成代码一般按语义命名:页面级文件在 pages/、app/、views/ 下,通用块在 components/ 下,名字多为 Layout、Header、Sidebar、CardList、DataTable、FilterBar、DetailPanel、EmptyState、Pagination。先按目录和文件名过一遍,比逐行读代码快,也方便把改数据和改样式分开排期。

可以直接留用的判断标准:

  • 组件只接收 props 或 children,文件里没有 import 数据文件,也没有 fetch、axios 调用;
  • 模板里的文案、图标、间距属于通用内容,不绑定某个业务字段名;
  • 加载态、空态、错误态的展示分支齐全,不需要重新设计;
  • 没有对字段做固定换算,例如金额除 100、时间戳乘 1000。

需要改的组件特征更明显:useState 的初始值是一个具体示例数组;useEffect 里直接请求或用 setTimeout 造数据;模板直接读 item.title、item.statusText 这类 mock 字段名;分页、排序、筛选是前端对静态数组做 slice 或 sort。这类组件保留外壳,把数据来源和执行逻辑换掉。

建议边看边登记,避免改到一半记不清:

文件路径组件结论原因
src/components/StatCard.jsxStatCard留用只吃 props
src/pages/OrderList.jsxOrderList改数据内联 mock 数组加 setTimeout
src/pages/UserDetail.jsxUserDetail重写请求字段名与后端不一致

找出数据来源被写死的位置

写死数据通常有四种形态:顶层常量数组(const listData = [...])、独立 mock 文件(mock/、fixtures/、__mocks__ 目录或 data.js)、组件内联数组(map 里直接写对象)、假装成请求的异步函数(setTimeout 里 resolve 一个常量)。前三种搜变量名和关键词能找到,第四种要看有没有 fetch 或 Promise.resolve。

可以先跑几条搜索把范围缩小:

grep -rnE 'mock|dummy|sample|fake|placeholder' src
grep -rnE 'setTimeout|Promise\.resolve|axios|fetch\(' src
grep -rn 'const .* = \[' src

逐处登记用一张短清单就够,每行四列:编号、文件与行号、写死类型、替换目标(哪个接口、哪些字段)。类型分三类即可:内联常量、独立 mock 文件、模拟请求。登记后按清单逐条改,改完划掉,比靠记忆核对可靠。

把请求逻辑单独抽成一层便于替换地址

组件里出现请求地址时,把它上移到单独一层:组件只调 api 模块的函数,api 模块调统一 request,request 读环境变量里的 base 地址。这样换地址、加 header、改错误处理都只动一处。

// src/api/request.js
const BASE = import.meta.env.VITE_API_BASE || '/api';

export async function request(path, options = {}) {
  const res = await fetch(BASE + path, {
    headers: { 'Content-Type': 'application/json', ...(options.headers || {}) },
    ...options,
  });
  if (!res.ok) throw new Error('HTTP ' + res.status);
  return res.json();
}

// src/api/order.js
import { request } from './request';

export const getOrderList = (params) =>
  request('/orders?' + new URLSearchParams(params).toString());

export const getOrderDetail = (id) => request('/orders/' + id);

环境变量按框架约定读取:Vite 用 .env 里的 VITE_API_BASE,代码写 import.meta.env.VITE_API_BASE;Next.js 用 .env.local 里的 NEXT_PUBLIC_API_BASE,代码写 process.env.NEXT_PUBLIC_API_BASE,只有带公开前缀的变量才会进到浏览器端。改完 .env 通常要重启 dev server,变量多在启动或构建时注入。

替换后的验证三步:一是在 request.js 里临时打印 BASE,确认取到的是自有地址而不是空值;二是打开 Network 面板刷新页面,看请求 URL 前缀是否与 .env 一致;三是把 BASE 临时改成一个不可达地址,确认页面走错误分支而不是白屏。验证完把临时日志删掉。

用一条自有数据走通列表到详情的链路

不必等所有接口就绪,先拿一条真实数据把列表到详情走通。检查点按顺序看:列表接口返回的是数组还是包了一层,res.data 与 res.data.list 的层级要和页面取值一致;列表每条记录的唯一标识字段名(id、_id、orderId)要和详情请求参数、路由参数对得上;详情页从 URL 取的 id 要和请求拼接的参数是同一个值;详情返回的字段名要和模板里读的字段名逐项对应;加载态、空态、错误态三个分支都能手动触发一次。

字段缺失时页面表现往往不明显:模板里 ${item.name} 会渲染出字符串 undefined;参与数字计算会得到 NaN;日期格式化会出现 Invalid Date;列表 key 用下标、字段又缺失时,React 可能复用错误节点,看起来像数据串了;图片 src 为空时浏览器会对当前页面再发一次请求,Network 里能看到。

确认渲染成功的做法:Network 中列表与详情各出现一次成功响应,且响应体里确实有数据;Elements 面板里列表条数等于响应条数;详情页每个字段和接口返回逐项对照一遍;控制台没有 key 重复警告和 undefined 相关报错。任一不满足,先回到第 2 节的写死清单,确认是不是还有旧数据在渲染。

把仍依赖生成假设的部分标注出来

有些假设无法靠搜索发现,只能标出来:接口没返回的字段(头像、昵称、备注)、单位不明的数值(分还是元、秒还是毫秒、时间戳还是 ISO 字符串)、分页与排序约定(page 从 0 还是 1、排序字段名、size 上限)、枚举值与文案的映射、时区、鉴权方式(token 放 header 还是 cookie)、错误码结构。

标注建议统一用可搜索的注释,格式固定,方便最后一次性清理:

// TODO(DATA): 详情接口未返回 author.avatar,暂用占位图,待确认
// TODO(DATA): status 枚举含义未知,当前按 0/1/2 映射文案,待后端确认
// TODO(DATA): amount 单位可能是分,展示与提交前的换算位置待确认

外部再维护一份清单,和注释内容对应:

编号文件:行依赖的假设影响范围处理方式
1src/pages/OrderDetail.jsx:42未返回 author.avatar头像展示占位图,待确认
2src/pages/OrderList.jsx:18status 枚举未知状态文案待接口方给映射表
3src/utils/format.js:7amount 单位为分金额展示确认后决定换算位置

处理顺序按是否阻塞联调分两批:阻塞的(id 字段、分页约定、鉴权、错误码)先找接口方确认,确认前不要靠猜写死;只影响展示的(占位图、文案、格式化)可以先用占位实现,但保留注释。每条处理完就把 TODO(DATA) 改成实际代码或删除,最后用 grep -rn 'TODO(DATA)' src 对一遍,剩余项应当都是有意识保留的。