核心是将请求抽象为函数参数,用闭包封装真实调用与 Mock 切换逻辑:业务代码只接收请求函数,不关心来源;通过工厂函数统一创建 requester 或服务实例,环境切换只需改配置,不侵入业务,且保留 Network 面板可见性与调试能力。
核心思路是把请求行为抽象成函数参数,用闭包封装真实调用与 mock 替换的切换逻辑,业务代码只接收函数,不关心来源。
把请求逻辑抽成可传入的函数参数
原始代码中硬编码 fetch 或 axios 是解耦失败的起点。改成让业务逻辑依赖“请求函数”本身:
- 错误写法:
useEffect(() => { fetch('/api/user') })—— fetch 是全局变量,无法替换 - 正确写法:
const useUser = (requestFn = fetch) => { useEffect(() => { requestFn('/api/user') }) } - 生产环境调用:
useUser()(自动使用原生 fetch) - Mock 环境调用:
useUser(mockFetch)(传入预定义的模拟函数)
用闭包封装 Mock 切换逻辑
在入口或配置层创建一个“请求工厂”,内部用闭包记住当前环境和 mock 策略:
- 定义
createRequester = (env) => { return (url, options) => env === 'mock' ? mockResponse(url) : fetch(url, options); } - 在顶层组件中:
const requester = createRequester(import.meta.env.MODE); - 所有 Hook 和 Service 都只接收并调用
requester,不感知环境 - 切换环境只需改
MODE值,无需动任何业务文件
配合工厂函数统一管理服务实例
避免 new ApiClient() 散落在各处,否则每次切 Mock 都得全局搜索替换:
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
- 新建
services.ts,导出createApiClient = (config) => new ApiClient(config) - 入口处一次性创建:
const services = { api: createApiClient({ baseUrl: '/mock' }) }; - 业务中通过
useContext(ServicesContext)或参数注入获取services.api - Mock 时只需替换
createApiClient返回 mock 实例,其余代码完全不动
不依赖全局拦截,保留 Network 面板可见性
相比重写 fetch/XHR 的方案,闭包注入方式不篡改全局行为:
立即学习“前端免费学习笔记(深入)”;
- 请求仍走标准 fetch,Network 面板能清晰看到 mock 请求(URL 可设为 /mock/api/xxx)
- 响应头可加
X-Mock: true标识,便于调试区分 - 不影响浏览器 DevTools 的时间线、缓存、CORS 等诊断能力
- 避免 better-mock 类库导致 fetch 消失、无法断点调试的问题

















