Mock.js 快速上手:安装引入与基础数据模板语法
本文详细介绍 Mock.js 的安装与引入方式,深入解析数据模板定义规范(DTD)的核心语法,包括字符串、数值、布尔值、对象和数组的规则定义与生成逻辑,帮助前端开发者快速掌握接口模拟技术。
在前后端并行开发时,前端工程师常常面临“接口未就绪导致业务逻辑无法联调”的困境。Mock.js 正是解决该矛盾的标准方案:它能在前端直接拦截 Ajax 请求,并通过直观的数据模板语法(DTD)生成高度随机且逼真的模拟数据。本文将从安装引入切入,逐层拆解数据模板语法规则与拦截原理,帮助你快速完成接口模拟开发。
一、Mock.js 的安装与环境引入
使用 Mock.js 的核心诉求是在开发阶段拦截网络请求。为了避免模拟代码污染生产构建包,推荐根据工程形态选择合适的引入方式。
1. Node.js 与模块化工程引入
在基于 npm/yarn/pnpm 的现代前端工程(如 Vue CLI、Create React App、Vite 等)中,应将 mockjs 安装在开发依赖中:
# 在项目根目录下执行安装命令
npm install mockjs -D
安装完成后,在代码中通过 ES 模块语法导入使用:
// 引入 Mock 对象
import Mock from 'mockjs';
// 或使用 CommonJS 规范引入
// const Mock = require('mockjs');
2. 浏览器直接引入(CDN 模式)
在传统多页项目或静态演示原型中,可以直接在 HTML 文件中通过 <script> 标签从公共 CDN 加载。加载后,Mock 对象将直接挂载到全局作用域 window 上:
<!-- 从国内常用 CDN 镜像加载 Mock.js -->
<script src="https://cdn.jsdelivr.net/npm/mockjs@1.1.0/dist/mock.min.js"></script>
<script>
// 直接通过全局 Mock 对象定义规则
console.log(Mock.mock({ 'name|1-3': '★' }));
</script>
3. 工程化项目的隔离目录建议
为了保证团队协作清晰,建议在项目的 src/ 目录下建立独立的 mock/ 目录,例如 src/mock/index.js。在入口文件 main.js 中,仅在开发环境变量生效时才动态载入该文件:
// src/main.js
if (process.env.NODE_ENV === 'development') {
import('./mock'); // 仅在开发环境中启用 Mock 拦截
}
二、核心拦截接口:Mock.mock() 的调用方式
Mock.mock() 是 Mock.js 的核心方法,根据传入参数的不同,主要有三种使用形态:
-
仅根据模板生成数据:
Mock.mock(template)
该形态不进行网络拦截,直接根据数据模板解析并返回一个 JavaScript 纯对象,常用于单元测试或单组件本地数据调试。 -
拦截请求并匹配模板响应:
Mock.mock(rurl, template)
当拦截到匹配rurl的 Ajax 请求时,自动根据template生成响应体并返回。 -
指定请求类型与回调响应:
Mock.mock(rurl, rtype, template | function(options))
进一步约束 HTTP 动词(如'get'、'post'),第三个参数可传入函数。函数接收包含请求路径、类型与请求体(body)的options参数,并返回最终结果。
/api/users?page=1&size=10),直接使用字符串 '/api/users' 将无法精确匹配。此时 rurl 参数应传入正则表达式:new RegExp('/api/users.*')。
三、数据模板定义语法(DTD)全解
Mock.js 最精妙的设计在于其数据模板定义语法(Data Template Definition, DTD)。通过统一的声明结构,开发者可以用最少的代码描述复杂的数据分布规律。
数据模板中的每个属性由 3 部分构成:
// 数据模板核心语法结构
'name|rule': value
name(属性名):最终生成的数据对象的键名。经过 Mock.js 解析后,竖线及后续规则都会被剔除。rule(生成规则):可选的控制指令,决定属性值如何基于初始值进行派生或重复。value(属性值):初始值,不仅给出生成数据的基准内容,还决定了生成属性的类型。
1. 字符串(String)规则
当 value 为字符串时,生成规则主要用于重复拼接:
'name|min-max': string:通过重复string生成字符串,重复次数为min到max之间的随机整数。'name|count': string:通过重复string刚好count次生成字符串。
// 字符串规则示例
const data = Mock.mock({
'title|1-3': '★', // 随机输出 "★"、"★★" 或 "★★★"
'echo|2': 'hello ' // 固定输出 "hello hello "
});
2. 数值(Number)规则
数值类型支持三种关键规则:自增递增、区间随机、浮点数精度。
'name|+step': number:计数器自增。属性值自动按step递增,每次调用Mock.mock()时在上一次结果基础上累加。'name|min-max': number:生成大于等于min且小于等于max的随机整数。'name|min-max.dmin-dmax': number:生成浮点数。整数部分在min到max之间,小数部分保留dmin到dmax位。
// 数值规则示例
const numData = Mock.mock({
'id|+1': 100, // 依次生成 100, 101, 102...
'age|18-60': 1, // 生成 18 至 60 之间的整数
'score|60-100.1-2': 1, // 生成如 85.6 或 92.45 的浮点数
'price|10-50.2': 1 // 固定保留 2 位小数,如 36.42
});
3. 布尔值(Boolean)规则
布尔值规则用于控制 true 与 false 的生成概率:
'name|1': boolean:随机生成布尔值,值为true或false的概率各占 50%。'name|min-max': value:值为value的概率是min / (min + max),值为!value的概率是max / (min + max)。
// 布尔值规则示例
const boolData = Mock.mock({
'isActive|1': true, // 50% true, 50% false
'isVip|1-4': true // 值为 true 的概率为 1/(1+4)=20%,false 概率为 80%
});
4. 数组(Array)规则
数组规则是前端构造列表数据最常用的手段,具有“抽取”和“重复扩充”两种完全不同的行为模式:
'name|1': array:从属性值array中随机选取 1 个元素作为最终属性值。'name|+1': array:从属性值array中按顺序依次选取 1 个元素作为最终属性值。'name|count': array:将属性值array中的元素完整重复count次,生成新数组。'name|min-max': array:将属性值array中的元素重复min到max次,生成新数组。
// 数组规则示例
const arrayData = Mock.mock({
'randomRole|1': ['Admin', 'Editor', 'Guest'], // 随机挑选一个角色
'userList|5-10': [ // 重复生成 5 到 10 个用户对象
{
'id|+1': 1,
'name': '@cname',
'status|1': true
}
]
});
5. 对象(Object)规则
当属性值为 JavaScript 对象时,规则控制的是从原对象中提取属性键值对的数量:
'name|count': object:从object中随机抽取count个属性。'name|min-max': object:从object中随机抽取min到max个属性。
// 对象规则示例
const objData = Mock.mock({
'tags|2': {
'vue': 'Vue.js',
'react': 'React',
'node': 'Node.js',
'ts': 'TypeScript'
}
// 输出结果仅保留随机选中的 2 个键值对
});
四、完整实战:构建用户分页查询接口
下面演示一个常见的前端列表 API 模拟场景:使用 Axios 发起 GET 请求,由 Mock.js 拦截并返回包含总数、当前页及列表数据的标准分页结构。
1. 编写 Mock 拦截规则
// src/mock/user.js
import Mock from 'mockjs';
// 拦截 GET /api/users 请求
Mock.mock(new RegExp('/api/users.*'), 'get', (options) => {
// options 包含 url、type、body
console.log('接收到请求:', options.url);
return Mock.mock({
code: 200,
message: 'success',
data: {
'total': 48,
'page': 1,
'pageSize': 5,
'list|5': [
{
'id|+1': 1001,
'name': '@cname', // 随机中文姓名
'email': '@email', // 随机邮箱
'age|20-45': 1, // 20至45岁
'city': '@city(true)', // 省市组合
'registeredAt': '@datetime', // 随机日期时间
'status|1': ['在线', '离线', '忙碌'] // 随机状态
}
]
}
});
});
2. 前端请求与结果验证
// 业务组件调用示例
import axios from 'axios';
axios.get('/api/users?page=1&pageSize=5')
.then(res => {
console.log('响应结果:', res.data);
})
.catch(err => {
console.error('请求失败:', err);
});
控制台打印的示例返回数据(实际字段值随机生成):
// 控制台示例输出(真实运行示例)
{
"code": 200,
"message": "success",
"data": {
"total": 48,
"page": 1,
"pageSize": 5,
"list": [
{
"id": 1001,
"name": "张伟",
"email": "w.zhang@foxmail.com",
"age": 28,
"city": "浙江省 杭州市",
"registeredAt": "2024-03-15 14:22:08",
"status": "在线"
},
{
"id": 1002,
"name": "李秀英",
"email": "x.li@163.com",
"age": 34,
"city": "广东省 深圳市",
"registeredAt": "2023-11-02 09:10:45",
"status": "离线"
}
// 其余 3 项自动补全...
]
}
}
五、关键避坑要点与排查建议
在初次使用 Mock.js 时,有几个机制层面的细节经常导致“为什么请求没被拦截”或“为什么无法调试”的疑惑:
Mock.js 的底层原理是重写了浏览器的
window.XMLHttpRequest 原生对象。如果项目使用 window.fetch() 发送请求,Mock.js 无法直接生效。若项目重度依赖 fetch,建议配合 fetch-mock、或采用构建工具层面的中间件方案(例如 vite-plugin-mock)。对于使用 axios 或传统 jQuery.ajax 的项目,Mock.js 能够完全透明兼容。
因为请求在到达浏览器网络栈之前已经被 Mock.js 的 XHR 代理拦截并在内存中直接返回,部分浏览器开发工具的 Network 面板默认不会录入该请求事件。如果需要排查,可以在 Mock 回调函数中添加
console.log 进行打印排查。
当后端接口开发完成进入联调阶段时,无需修改任何业务请求代码。只需在入口文件(如
main.js)中注释掉 import './mock',前端发出的请求就会自然流转到真实后端服务,实现开发到联调的无缝平滑过渡。
在 NestJS 中使用管道验证数据与守卫控制访问权限
2026-11-05 12:43:41
Node.js后端生成高强度随机字符串的方法
2026-11-04 16:29:54
Node.js环境中怎么使用axios或http模块发送GET请求
2026-11-03 21:57:15
Node.js环境下怎么实现JS反混淆自动化?常用库与CLI工具推荐
2026-11-03 21:15:54
解决JS逆向常见报错:缺少DOM环境导致代码运行失败
2026-11-03 20:41:59








