介绍
Mockjs 是一个用于前后端分离开发的工具,可以拦截 Ajax 请求,返回模拟的响应数据。换言之,前后端分离模式下的前端开发者可以独立于后端进行开发,无需后端先定义返回的数据结构再开始开发,可以完善前端工程开发链路,可无缝对接后端接口。
引入
- 创建Vue3项目,参考Vue.js创建教程。
- 添加mockj.js依赖,最终package.json的devDependencies属性会添加'"mockjs": "^1.1.0"'。
csharp
# npm
npm i mockjs -D
# yarn
yarn add mockjs --dev
- 引入mockjs。在main.js文件中,添加以下代码行。
js
// 如果需要按照启动环境则放开注释
// if (process.env.NODE_ENV === 'development') {
// import('./mock').then(({ default: mock }) => {
// console.log('mock启动成功');
// })
// }
// 直接引入
import('./mock')
import { createApp } from 'vue'
// 假如需要再App.vue生命周期时拦截Ajax,mockjs需先启动,否则无法拦截
// App.vue的请求可设置50ms的延迟
import App from './App.vue'
import router from './router'
在src下创建mock文件夹,编辑index.js
js
import Mock from 'mockjs'
// 设置响应延迟,可注释
Mock.setup({
timeout: 500
})
// Mock.mock('路由', 'http请求方法', '返回内容')
console.log('已注册 Mock 路由:', Mock._mocked)
至此,引入mockjs已经完成,使用npm run dev看见控制台输出证明成功。
业务场景
使用前,你需要有Ajax发起http请求,按照你的业务逻辑访问一个后端接口路径,最终被mockjs拦截返回需要的模拟数据。
例如:访问'/home/info'路由,使用'GET'方法,返回数据结构如下:
json
{
code: 200,
msg: 'success',
data: {
userId: '1',
name: 'admin',
avatarUrl: '/static/avatar.jpg',
roles: ['admin']
}
}
以此处为例,提前封装axios,步骤省略。
在views下新建home目录,并在route中定义home页面的访问路由,省略。
在home目录下新建api/index.js,按照正常业务逻辑编写API内容
js
import { get, post, put, del } from '@/utils/request'
export const homeApi = {
getInfo(){
return get('/home/info')
}
}
编写home/index.vue文件内容
vue
<template>
<div class="body">
{{ userInfo.name }}
</div>
</template>
<script setup>
import { ref, reactive, onMounted, defineProps, defineEmits, watch, computed } from 'vue'
import { homeApi } from './api'
// Data
const userInfo = ref({})
// Lifecycle hooks
onMounted(() => {
queryInfo()
})
// Methods
const queryInfo = () => {
homeApi.getInfo().then(res => {
console.log(res);
if(res.code === 200){
userInfo.value = res.data
}
})
}
</script>
到目前为止,我们的开发流程还是根据正常的业务逻辑进行开发的,没有在代码中使用硬编码或FakeData获取数据,正常发起接口请求,并期望获取后端返回数据。下一步,我们需要使用mock.js将后端业务返回的数据进行定义,并正确拦截请求进行返回。
编写上文已新建的mock/index.js文件
js
// 添加
// 正则匹配
Mock.mock(/user\/info/, 'get',() => {
return {
code: 200,
msg: 'success',
data: {
userId: '1',
name: 'admin',
avatarUrl: '/static/avatar.jpg',
roles: ['admin']
}
}
})
启动项目,访问home路由,查看控制台或页面输出。

使用小记
前文已经描述了如何使用mockjs,在此记录下相关已经踩坑的内容,或使用变种。
- 返回多个数据或动态内容,更多内置方法参考点此
json
// 在返回的json中支持多个数据生成,或内置方法支持动态数据
{
code: 200,
message: '成功',
// 返回3~5个元素的列表
'data|3-5': [
{
'id|+1': 1,
'cId': '@id', // 生成id
'name': '@cName', // 生成中文名称
'createTime': '@datetime', // 时间
'updateTime': '@datetime',
// 1-5个数据内容
'children|1-5': [
{
'id|+1': 1,
'parentId': '@id',
'index|+1': 1,
'name': '@cName
}
]
}
]
}
- 自定义拓展方法
js
// 在mock/index.js编写
Mock.Random.extend({
userName(){
const names = ['张三', '李四', '王五', '赵六', '孙七', '周八', '吴九', '郑十']
return names[Math.floor(Math.random() * names.length)]
}
})
// 上述方法已经添加了一个userName的拓展方法,在返回的数据属性中使用'@userName'即可
- 在App.vue中使用
vue
// App.vue在项目启动时生命周期触发时mockjs还没有加载完成,因此可能需要设置延迟访问才会被mockjs拦截
onMounted(() => {
setTimeout(() => {
query()
}, 200)
})
- 模板化返回内容
js
// 上文编写的Mock.mock方法中返回内容是直接编写在回调方法中的
// 编写多个时不直观、不美观
// 可以将返回的对象封装成常量引入mock/index.js中
import Mock from 'mockjs'
import { homeTemplate } from './template/homeTemplate'
Mock.mock(/user\/info/, 'get', homeTemplate.queryInfo)
homeTemplate.js
export const homeTemplate = {
queryInfo: {
code: 200,
msg: 'success',
data: {
userId: '1',
name: 'admin',
avatarUrl: '/static/avatar.jpg',
roles: ['admin']
}
}
}
- 匹配路径方式
js
// 请求路径http://localhost:8080/home/info/{userId}
Mock.mock(/home\/info\/\d+/, 'get', homeTemplate.queryInfo)
// 请求路径http://localhost:8080/home/info
Mock.mock(/home\/info\/\d+/, 'get', homeTemplate.queryInfo)
Mock.mock('http://localhost:8080/home/info', 'get', homeTemplate.queryInfo)