核心是将网络请求逻辑解耦于业务代码,通过接口抽象(如ApiRequester类型)和工厂函数(createApiClient)实现真实/_mock_环境切换;统一在入口创建services对象并注入,配合运行时环境变量或本地存储动态选择实现,避免硬编码和重复实例化。

核心是让网络请求逻辑不固化在业务代码里,而是由外部决定用真实接口还是 Mock 实现——只要依赖创建和调用分离,环境切换就变成配置问题,而非改代码。
把请求能力抽象成接口,不绑定具体实现
前端虽无强类型接口,但可以用函数签名或 TypeScript 类型定义契约。例如声明一个 ApiRequester 类型:
- type ApiRequester = (url: string, options?: RequestInit) => Promise<any>
- 所有业务逻辑(如自定义 Hook、Service 类)只依赖这个类型,不 import 或 new 任何具体 client
- 真实环境传入
fetch或axios.get;测试环境传入返回预设数据的 mock 函数
用工厂函数统一构造网络实例,避免 new 散落各处
禁止在组件、Hook 或工具函数里直接写 new ApiClient()。新建 services/api.ts 集中管理:
- 导出 createApiClient(options) 工厂函数,接收 base URL、拦截器等可配置项
- 入口文件(如 main.tsx)中一次性调用它,生成实例并存入全局 services 对象
- 后续所有模块都从 services 取 api 实例,而不是自己创建
Mock 场景下,只需让 createApiClient 返回一个模拟实现(如返回固定 JSON 的函数),其余代码完全不动。
前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。
立即学习“前端免费学习笔记(深入)”;
通过顶层注入服务对象,而非单个实例
Vue 的 provide/inject 或 React 的 Context 不是用来传 new ApiClient() 的,那会提前实例化、无法延迟控制。
- 正确做法:在根组件 provide 一个已组装好的 services 对象(含 api、logger 等)
- 子组件用 inject 获取整个 services,再取
services.api调用 - 这样既支持按需初始化(比如 api 实例可带 lazy 初始化逻辑),也便于类型推导和统一替换
配合环境变量做运行时决策,不重新打包也能切环境
构建时确定环境不够灵活,尤其本地开发常需临时切 Mock。可在入口加一层轻量路由逻辑:
- 检查
import.meta.env.VITE_USE_MOCK === 'true'或读取 localStorage 标志 - 据此决定调用
createApiClient还是createMockApiClient - 甚至支持运行时按钮切换:点击后重置 services 并触发全局刷新(如 React 的
useReducer触发重渲染)
不复杂但容易忽略

















