vue-mock
v0.2.1
Published
> 浏览器端 HTTP 请求 **录制 / 回放** 工具,可直接用于任意前端项目,并保留 Vue 插件式接入方式。
Readme
vue-mock
浏览器端 HTTP 请求 录制 / 回放 工具,可直接用于任意前端项目,并保留 Vue 插件式接入方式。
vue-mock 通过 ajax-hook 在浏览器中拦截 XMLHttpRequest,可以将真实接口的请求/响应录制下来,之后在没有后端的环境中(联调断网、演示、E2E 测试等)以本地数据进行回放。
- 支持 原生 JS / React / Vue 2.7+ / Vue 3 等浏览器前端项目
- 支持
XMLHttpRequest与浏览器fetch的录制 / 回放 - 存储后端可选
localStorage或indexedDB - 控制台内置,无需额外引入 UI 库
- 录制 / 回放 两种模式互斥
- 支持状态码回放、归一化请求匹配、导入导出、脱敏规则和单条记录管理
安装
pnpm add vue-mock
# 或
npm i vue-mockvue-mock 的核心和控制台不依赖 Vue、React 或其他宿主框架。Vue 项目仍可继续使用原来的插件 API。
快速上手
原生 JS / 任意框架
// main.ts
import { installMock } from 'vue-mock/vanilla';
import 'vue-mock/dist/style.css';
installMock({
hideCtrl: false, // 是否默认隐藏控制台
openMockRecord: false, // 是否默认开启「录制」模式
openMockMode: false, // 是否默认开启「回放」模式(与录制互斥)
mode: 'localStorage', // 'localStorage' | 'indexedDB'
});React
// main.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import { installMock } from 'vue-mock/vanilla';
import 'vue-mock/dist/style.css';
import App from './App';
installMock({ mode: 'indexedDB' });
createRoot(document.getElementById('root')!).render(<App />);Vue 3
// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import VueMock from 'vue-mock';
import 'vue-mock/dist/style.css';
createApp(App)
.use(VueMock({
hideCtrl: false, // 是否默认隐藏控制台
openMockRecord: false, // 是否默认开启「录制」模式
openMockMode: false, // 是否默认开启「回放」模式(与录制互斥)
mode: 'localStorage', // 'localStorage' | 'indexedDB'
}))
.mount('#app');这个用法保持向后兼容;内部实际调用的是同一套框架无关安装逻辑。
Vue 2.7
// main.ts
import Vue from 'vue';
import App from './App.vue';
import VueMock from 'vue-mock';
import 'vue-mock/dist/style.css';
Vue.use(VueMock({ mode: 'indexedDB' }));
new Vue({ render: h => h(App) }).$mount('#app');控制台并不挂在宿主应用上,而是由
vue-mock自己创建 DOM,挂到document.body下一个固定节点(#${elementId}),避免和宿主应用的框架状态、样式产生耦合。
使用方式
页面加载后,右下角会出现 vue-mock 悬浮控制台,可以:
- 切换「录制」/「回放」开关,状态自动持久化到
localStorage - 拖拽控制台到页面任意可视位置,刷新后保持位置
- 默认隐藏控制台时,可通过右下角小按钮或
Shift + M重新显示 - 查看请求命中/未命中诊断,确认 URL、method/body key、命中记录、未命中原因和录制状态
- 使用场景集管理 mock 数据,例如“空数据”“异常 500”“分页第 3 页”,并支持切换、复制、导入和导出
- 查看、搜索、按 method/status/tag 过滤、编辑、复制、禁用、批量删除 mock 记录
- 导入 JSON、导出当前场景或完整场景集,或确认后一键清空
- 配置脱敏规则,在录制和导出时替换响应、请求 body、query 和 headers 中的敏感字段
典型工作流:
- 启动应用,开启录制,正常使用页面让接口跑一遍 → 数据自动入库;
- 关闭录制,开启回放 → 之后命中的接口将直接返回本地存储的响应,未命中的接口仍走真实请求;
- 如果未命中,打开「请求诊断」查看具体原因,再决定补录、调整匹配规则或修改未命中策略;
- 需要演示或联调不同状态时,打开「管理 mock 数据」切换或复制场景;
- 需要分享 mock 数据时,用控制台导出 JSON 或场景集,导出前会再次应用脱敏规则。
工作原理
插件 install 时一次性安装全局 ajax-hook 代理,并在浏览器支持时一次性包装 window.fetch,整页生命周期内只挂载一次。运行行为由两个响应式开关控制:
- 录制(
openMockRecord):在响应回调中把{ url, method, body, requestHeaders, result, headers, status, statusText, responseType }写入当前场景;如果配置了脱敏规则,会先脱敏再落库; - 回放(
openMockMode):在请求回调中按当前场景中的启用记录进行匹配,命中则直接返回本地响应状态、响应头和响应体,未命中按missPolicy处理。
fetch 录制会通过 response.clone().text() 保存文本形式的响应体,因此最适合 JSON / text 接口;Blob、ArrayBuffer、流式响应等二进制场景暂不保证完整保真。
请求匹配会处理以下常见波动:
- HTTP method 大小写差异;
- query 参数顺序差异,如
/api?a=1&b=2与/api?b=2&a=1; - JSON 请求体字段顺序差异,如
{"a":1,"b":2}与{"b":2,"a":1}。 - 每条记录可通过
match配置忽略 query/body/header 字段、按 path pattern 匹配、要求特定 header; enabled: false的记录会保留在场景中,但不会参与回放匹配。
脱敏规则支持顶层字段、嵌套字段和数组项字段,例如 phone、user.phone、users.phone。规则可通过 scope 应用于响应结果、请求 body、URL query、headers 或全部范围。默认会跳过并遮罩 authorization、cookie、set-cookie、proxy-authorization、x-api-key 等敏感 header。规则会在录制时应用一次,导出时也会再次应用,但导出不会反向修改已存储记录。
记录还支持以下回放模拟字段:
{
"url": "/api/user/1",
"method": "GET",
"body": "",
"result": { "id": 1, "servedAt": "{{$timestamp}}" },
"headers": { "content-type": "application/json" },
"tags": ["demo"],
"enabled": true,
"match": {
"pathPattern": "/api/user/:id",
"ignoreQueryKeys": ["timestamp"],
"ignoreBodyKeys": ["nonce"],
"ignoreHeaderKeys": ["x-request-id"],
"headers": { "x-tenant": "demo" }
},
"delay": 500,
"networkError": false,
"randomErrorRate": 0.2,
"template": true
}template: true 时会替换 {{$timestamp}}、{{$isoTime}}、{{$request.method}}、{{$request.url}}、{{$request.path}}、{{$request.body}} 和 {{$randomInt:min:max}}。
两种模式互斥,同时开启会在 install 阶段抛错:mock记录与mock模式只能开启一个。
配置项
所有配置都在安装时传入:
import VMock from 'vue-mock'
VMock({
openMockMode: true,
missPolicy: 'error',
}).install()| 字段 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| hideCtrl | boolean | false | 是否默认隐藏悬浮控制台。只影响面板显示,不影响拦截、录制和回放。 |
| openMockRecord | boolean | false | 是否默认开启录制模式。开启后会把真实接口响应保存到当前场景。 |
| openMockMode | boolean | false | 是否默认开启回放模式。开启后会优先用本地 mock 数据响应请求。与 openMockRecord 互斥,不能同时为 true。 |
| dbKey | string | 'v__mock' | mock 数据的主存储 key。多个项目或多个演示数据集共用页面时应使用不同 key,避免互相覆盖。 |
| btnDbKey | string | 'v__mock__btn' | 控制台开关状态的 localStorage key。用于记住用户在面板中切换的录制/回放状态。 |
| elementId | string | 'v_mock' | 控制台挂载节点的 DOM id。vue-mock 会在 document.body 下创建这个节点,多个实例需要保持唯一。 |
| mode | 'localStorage' \| 'indexedDB' | 'localStorage' | mock 数据存储后端。localStorage 便于调试和复制,indexedDB 更适合较大的录制数据。 |
| indexedDBName | string | 'v__mock' | IndexedDB 数据库名。仅在 mode: 'indexedDB' 时生效。 |
| missPolicy | 'passthrough' \| 'error' \| 'prompt' | 'passthrough' | 回放未命中时怎么处理:passthrough 继续请求真实接口;error 返回 mock miss 错误;prompt 记录需要关注的诊断并默认透传。 |
| match | MatchRules | undefined | 全局默认匹配规则。用于忽略日期、时间戳、随机数、请求 ID 等易变条件;单条记录里的 match 会覆盖全局规则。 |
| shouldRecord | (context) => boolean \| { value, reason } | undefined | 录制前判断是否保存该请求。适合跳过健康检查、埋点、轮询等无用接口。 |
| shouldReplay | (context) => boolean \| { value, reason } | undefined | 回放前判断是否让当前请求参与 mock 匹配。返回 false 后按 missPolicy 处理。 |
| transformRecord | (record, context) => record \| null \| undefined | undefined | 录制落库前改写记录。常用于删除动态字段、补充 tags、统一脱敏;返回 null 表示不保存。 |
| customMatcher | (context) => record \| false \| { record, matched, reason } | undefined | 自定义回放匹配逻辑。默认匹配规则表达不了业务语义时使用,例如把演示环境的动态日期映射到固定录制数据。 |
| onHit | (context) => void | undefined | 回放命中后触发,可用于调试日志或统计命中率。 |
| onMiss | (context) => void | undefined | 回放未命中后触发,可用于提示缺失的 mock 条件。 |
| onRecord | (context) => void | undefined | 录制完成后触发,可用于输出保存日志或同步外部工具。 |
match 匹配规则
默认情况下,回放会比较 method、URL 和请求 body。match 用来声明哪些差异不影响命中。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| pathPattern | string | URL 路径模式。支持 :id 单段动态参数和 * 通配符,例如 /api/users/:id。配置后按 pathname 匹配,不要求记录 URL 与请求 URL 完全一致。 |
| ignoreQueryKeys | string[] | 忽略 URL query 参数。适用于 /api/list?date=2026-06-10、?timestamp=... 这类 GET 查询条件。 |
| ignoreBodyKeys | string[] | 忽略 JSON 请求 body 字段。适用于 POST/PUT body 里的 date、timestamp、params.date 等字段。 |
| ignoreHeaderKeys | string[] | 忽略请求头字段,比较时不区分大小写。适合忽略 x-request-id、trace id 等动态 header。 |
| headers | Record<string, string> | 要求请求必须携带并且值一致的 header。适合同一路径在不同租户、账号、环境下返回不同数据的场景。 |
示例:今天录制的 JSON 中日期是 2026-06-10,明天演示时请求默认变成 2026-06-11。如果日期只是默认查询条件,不影响你要演示的数据语义,可以忽略这个字段:
VMock({
openMockMode: true,
missPolicy: 'error',
match: {
// 日期在 URL 上,例如 /api/list?date=2026-06-11
ignoreQueryKeys: ['date', 'startDate', 'endDate'],
// 日期在 POST body 上,例如 { "date": "2026-06-11" }
ignoreBodyKeys: ['date', 'params.date'],
},
}).install()ignoreQueryKeys 和 ignoreBodyKeys 只影响“是否命中 mock”的判断,不会修改真实请求,也不会改写已保存的 JSON。
钩子上下文
shouldRecord、shouldReplay、transformRecord、customMatcher、onHit、onMiss、onRecord 都会收到 context,常用字段如下:
| 字段 | 说明 |
| --- | --- |
| request | 当前被拦截的请求,包含 url、method、body、headers。 |
| record | 当前命中的 mock 记录;只有命中或录制相关回调中可能存在。 |
| records | 当前激活场景中的全部记录,常用于 customMatcher 自行选择记录。 |
| scene | 当前激活的 mock 场景。 |
| diagnostic | 本次请求对应的诊断信息。 |
| reason | 命中、未命中、跳过录制等决策原因。 |
示例:
import VMock from 'vue-mock'
VMock({
openMockMode: true,
missPolicy: 'error',
match: {
ignoreQueryKeys: ['timestamp', '_t'],
ignoreBodyKeys: ['nonce', 'token'],
ignoreHeaderKeys: ['x-request-id'],
},
shouldRecord: ({ request }) => !request.url.includes('/health'),
transformRecord: record => ({
...record,
tags: [...(record.tags || []), 'demo'],
}),
onMiss: ({ request, reason }) => {
console.warn('[vue-mock miss]', request.method, request.url, reason)
},
}).install()