前言
前端开发最怕什么?等后端接口。
后端同学说"接口下周给",你的页面就卡在那里,联调时间一拖再拖。前后端分离的口号喊了很多年,但真正能做到"前端不依赖后端独立开发"的团队并不多。
这篇文章不讲大道理,直接以一个 Todos 全栈项目 为例,手把手展示前端如何通过 Mock 接口工程 实现完全独立的开发流程。你不需要等后端------把页面、路由、数据状态、接口全部在前端闭环跑通,后端接口好了之后,一行配置切换。
项目总览
bash
todos-fullstack/
├── readme.md
├── backend/ # 后端(Node + Koa + MySQL)
│ └── package.json
└── frontend/
└── todos/
├── index.html
├── vite.config.js # Vite 配置 + Mock 插件
├── package.json
├── mock/
│ └── todos.js # Mock 接口定义
└── src/
├── main.jsx # 入口
├── App.jsx # 根组件
├── api/ # 前端接口层
│ ├── config.js # Axios 配置
│ └── todos.js # 接口定义
├── components/
│ └── Nav.jsx # 导航组件
└── pages/
├── Home.jsx # 首页
└── Todos.jsx # 待办页
前端独立开发的三驾马车
一个现代前端应用,本质上由三样东西构成:
| 层次 | 职责 | 本项目对应 |
|---|---|---|
| 组件(响应式) | UI 渲染与交互 | components/ + pages/ |
| 路由 | 页面跳转 | React Router(Nav 导航) |
| 状态管理 | 数据流 | useState + API 请求 |
这三者构成了前端的"骨架"。但还有一个容易被忽视的"血液"------数据从哪里来?
为什么前端需要自己的 API 层?
传统流程是:
前端写好页面 → 等后端给接口 → 联调 → 上线
这个流程的核心矛盾在于:前后端开发节奏不同步。后端要先设计数据库、写业务逻辑,才能给出接口;而前端写完页面后只能干等。
解决方案很简单------在前端工程里引入 API 层,用 Mock 数据让前端自给自足:
前端写好页面 → 前端 Mock 接口 → 自测通过 → 后端接口就绪 → 一键切换
第一步:封装 Axios,统一管理请求
src/api/config.js:
js
import axios from 'axios';
const instance = axios.create({
baseURL: '/api', // 开发阶段走 Mock,所有请求前缀 /api
// baseURL: 'http://localhost:3000', // 后端就绪后,改这一行即可
timeout: 5000,
});
export default instance;
这里的关键设计是 baseURL。开发阶段指向 /api,Vite 的 Mock 插件会拦截这些请求;后端好了之后,改成 http://localhost:3000,所有请求自动切到真实后端------零侵入,只改一行。
第二步:定义接口模块
src/api/todos.js:
js
import axios from './config';
// 一个模块一个文件,职责清晰
export const getTodos = async () => {
const res = await axios.get('/todos');
return res.data;
};
api/ 目录的职责就是提供数据接口。每个后端接口对应一个函数,组件只关心"调用函数拿数据",不关心数据来自 Mock 还是真实后端。
第三步:Mock 数据,前端自给自足
mock/todos.js:
js
export default [
{
url: '/api/todos',
method: 'get',
timeout: 2000,
response: (req, res) => ({
code: 0,
todos: [
{ id: 1, title: '学习前端接口工程', completed: true },
{ id: 2, title: '看龙餐馆', completed: false },
],
}),
},
];
Mock 文件的结构非常直观------定义 url、method、timeout(模拟网络延迟)、response(返回数据)。这和后端接口文档的格式几乎一致,后端同学看了也能立刻理解。
第四步:Vite 插件,让 Mock 跑起来
vite.config.js:
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, // 本地开发启用
}),
],
});
vite-plugin-mock 会在 Vite 开发服务器中拦截匹配 /api/todos 的请求,直接返回 Mock 数据。前端开发体验和连真实后端完全一致------你甚至可以在 Network 面板看到请求和响应。
第五步:组件消费数据
src/pages/Todos.jsx:
jsx
import { getTodos } from '../api/todos';
import { useEffect, useState } from 'react';
function Todos() {
const [todos, setTodos] = useState([]);
useEffect(() => {
(async () => {
const data = await getTodos();
setTodos(data);
})();
}, []);
return (
<div>
{todos.map(todo => (
<div key={todo.id}>
<span>{todo.title}</span>
<span>{todo.completed ? '✅' : '❌'}</span>
</div>
))}
</div>
);
}
export default Todos;
组件只做三件事:
- 用
useState声明响应式状态 - 用
useEffect在挂载时调用接口 - 用拿到的数据渲染 UI
这个组件不关心数据来源------Mock 也好、真实后端也好,对它来说没有任何区别。
切回真实后端,只需要改一行
当后端接口就绪后,只需要在 src/api/config.js 中修改 baseURL:
js
// 从
baseURL: '/api',
// 改为
baseURL: 'http://localhost:3000',
就这么简单。 所有组件代码、接口调用代码完全不需要动。
总结:前端接口工程的核心思想
| 传统模式 | 接口工程模式 |
|---|---|
| 后端先给接口,前端才能写 | 前端 Mock 先行,后端并行开发 |
| 联调阶段大量阻塞 | Mock 阶段自测通过,联调只做验证 |
| 接口地址散落在各处 | 统一在 api/config.js 管理 |
| 切换后端要改无数文件 | 改一行 baseURL |
前端接口工程不是什么高大上的概念,它就是把"等后端"这个环节从前端开发流程中拿掉。你的组件、路由、状态管理可以完全独立地跑起来,Mock 数据足够支撑整个开发阶段。
前端不等人,先从 Mock 开始。
本文基于 React + Vite + vite-plugin-mock 实践编写,完整代码见项目目录。
延伸阅读:
react-router-dom路由管理、zustand全局状态管理、Koa 后端接口开发。