「后端接口下周才给,前端页面这周就要交付。」
这句话,大概是前后端分离项目里,前端听到最多次的噩梦开场。
前端难道只能干等?

不用。 前端完全可以先把整个 App 独立跑起来,界面、路由、状态、交互全部自给自足,唯一的等待点——后端接口——用 Mock 顶上去。
这篇文章带你从 0 搭一套前端 API 工程,读完你能拿到:
- 统一管理接口的 api/ 目录
- 一行代码切换 Mock / 真实后端
- 完整可运行代码 + 5 个踩坑提醒
全程 3 步,10 分钟就能跑起来。
项目开始前:先想清楚一件事
前后端分离的项目,前端有自己的三驾马车:
组件(响应式)+ 路由 + 状态管理
它们撑起了整个独立的前端应用。但前端真的彻底独立了吗?没有,还剩最后一个耦合点:
/api 接口。
页面要渲染数据,就得向后端要。后端开发慢、排期晚,前端就卡住——这就是"傻等后端"的根源。
所以解决方案不是等,而是:前端自己先造一个"接口后端",等真后端就绪,再一键切过去。
这就是前端 API 工程。
第一步:搭一个 api 目录,统一管理所有接口
很多项目里,请求东写一个 fetch,西写一个 axios,散落在各个组件里。
一旦后端改路径、换域名,前端就得满项目找,改到怀疑人生。
正确做法:建一个 api/ 目录,把前端所有的接口请求统一收编。
先建一个 axios 实例,统一配置:
// src/api/config.js —— 全局唯一 axios 实例
import axios from 'axios';
const instance = axios.create({
baseURL: '/api', // 开发阶段:走 vite mock
// baseURL: 'http://localhost:3000', // 后端就绪后:一键切换
timeout: 5000, // 5 秒超时
});
export default instance;
再按模块拆分接口文件,一个模块一个 js:
// src/api/todos.js —— todos 相关的接口
import axios from './config';
export const getTodos = async () => {
const res = await axios.get('/todos');
return res.data;
};
注意:get('/todos') 加上 baseURL /api,实际请求是 /api/todos。
组件里再也看不到 axios 长什么样,只调用 getTodos()。接口层从此和后端一样,可以独立演进。
第二步:vite-plugin-mock,2 行配置把"后端"跑起来
接口层有了,谁来响应?
Mock。
用 vite-plugin-mock,在 vite.config.js 里加两行配置:
// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { viteMockServe } from 'vite-plugin-mock'
export default defineConfig({
plugins: [
react(),
viteMockServe({
mockPath: 'mock', // mock 文件目录
localEnabled: true, // 开发环境开启
}),
],
})
然后在项目根目录建 mock/todos.js,模拟后端返回:
// mock/todos.js —— 前端自己的"后端"
export default [
{
url: '/api/todos',
method: 'get',
timeout: 2000, // 模拟网络延迟
response: (req, res) => ({
code: 0, // 约定:0 表示成功
todos: [
{ id: 1, title: '学习前端接口工程', completed: true },
{ id: 2, title: '看龙餐馆', completed: false },
],
}),
},
];
启动 npm run dev,浏览器访问 http://localhost:5173/api/todos,数据就回来了。
界面还没写完的时候,你还能把 Mock 里的数据结构当成"接口契约"丢给后端:按这个字段给我。
第三步:页面里调用,组件只关心数据
Mock 就绪,页面就可以完全独立开发了:
// src/pages/Todos.jsx
import { getTodos } from '../api/todos';
import { useEffect, useState } from 'react';
function Todos() {
const [todos, setTodos] = useState([]);
useEffect(() => {
// IIFE:立即执行函数,包住 async/await
(async () => {
const data = await getTodos();
setTodos(data);
})();
}, []);
return (
<ul>
{todos.map((t) => (
<li key={t.id}>{t.completed ? '已完成' : '未完成'}:{t.title}</li>
))}
</ul>
);
}
export default Todos;
到这里,前端从路由到数据,整个 App 已经能独立跑完。 页面路由交给 react-router-dom,接口路由交给 api/ 目录,各司其职。
一键切换:从 Mock 到真实后端
后端接口终于写好了,切过去只需要改一个地方:
// src/api/config.js
const instance = axios.create({
baseURL: 'http://localhost:3000', // 真实后端
timeout: 5000,
});
一行配置,全局生效。
所有页面、所有组件都不用动。这就是把接口收进 api/ 目录的最大好处:切换成本约等于 0。
踩坑提醒:5 个我踩过的坑
url 别漏了 /api 前缀
baseURL 是 /api,mock 里的 url 也必须是 /api/todos。漏一个前缀,页面永远拿不到数据,光报 404。
mock 文件必须 export default 数组
vite-plugin-mock 只认默认导出,写成 export const 会直接不生效,而且不报错——最难查的那种。
localEnabled 记得区分环境
开发环境开启,生产环境必须关闭(默认关闭)。否则线上 build 会夹带 mock 代码,真实接口直接被"劫持"。
渲染列表要写 key
key={t.id} 不写,列表一长,控制台全是 warning,更新时还会出各种诡异 bug。
切到真实后端后,跨域是下一个坑
本地 5173 请求 3000,跨域。开发环境可以配 Vite 的 server.proxy,让后端在代理后面无感切换。
总结:前端 API 工程,值不值得做?
值。
表面上,它只是多了个 api/ 目录和几行 mock 配置。
但长期看,它带来三样东西:
- 前端不再等后端,开发节奏自己掌控
- 接口统一管理,改地址、换域名,只动一个文件
- Mock 即契约,数据结构提前锁定,联调成本大幅下降
前后端分离,分离的不仅是代码,更是各自的开发节奏。
而前端 API 工程,就是那条把节奏握在自己手里的线。
最后
你也在等后端排期吗?还是说,你们团队已经在用 mock 开发了?
评论区聊聊你的"等接口"故事。
网硕互联帮助中心





评论前必须登录!
注册