项目集成 Mock 数据
# 项目集成 Mock 数据
在前后端分离开发模式下,前端通常需要在后端 API 尚未完成时,使用 Mock 数据 来模拟真实接口。Vite 提供了 vite-plugin-mock
插件,可以帮助我们快速搭建 Mock API,与 mockjs
结合,可以高效模拟真实的后端服务。
# 1. 为什么要使用 Mock 数据?
在开发过程中,我们可能会遇到以下问题:
- 后端接口未完成,前端无法调试 API。
- 后端数据变动频繁,每次修改都需要等待后端部署。
- 测试不同返回数据,方便前端处理各种业务场景。
- 避免频繁请求真实后端,降低开发环境的压力。
使用 Mock 数据,可以让前端不依赖后端,也能提前开发、调试接口,提高开发效率。
# 2. 安装 Mock 依赖
在 Vite 项目中,我们使用 vite-plugin-mock
插件来创建 Mock API,并使用 mockjs
来生成模拟数据。
pnpm install -D vite-plugin-mock@2.9.6 mockjs
或者:
npm install -D vite-plugin-mock@2.9.6 mockjs
# 或
yarn add -D vite-plugin-mock@2.9.6 mockjs
2
3
# 3. 在 Vite 中配置 Mock 插件
# 🔹 2.x 版本配置
如果你使用的是 vite-plugin-mock@2.x
(如 2.9.6
),请使用以下配置:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { viteMockServe } from 'vite-plugin-mock';
const isDev = process.env.NODE_ENV === 'development'; // 通过环境变量判断
export default defineConfig({
plugins: [
vue(),
viteMockServe({
localEnabled: isDev, // ✅ 仅在开发环境启用 Mock
mockPath: 'mock', // ✅ 指定 Mock 文件目录,默认为 "mock"
logger: true, // ✅ 开启日志,控制台输出 Mock 请求日志
}),
],
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 🔹 3.x 版本配置
如果你使用的是 vite-plugin-mock@3.x
(如 3.0.0
及以上),配置方式有所不同:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { viteMockServe } from 'vite-plugin-mock';
export default defineConfig(({ command }) => ({
plugins: [
vue(),
viteMockServe({
mockPath: 'mock', // 指定 Mock 文件目录
enable: command === 'serve', // 3.x 版本使用 `enable` 代替 `localEnabled`
logger: true,
injectCode: `
import { setupProdMockServer } from '../mock/mock-server';
setupProdMockServer();
`,
}),
],
}));
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
🚀 主要区别
版本 | 配置项 | 说明 |
---|---|---|
2.x | localEnabled | true/false ,控制是否启用 Mock |
3.x | enable | true/false ,用 enable 替换了 localEnabled |
3.x | injectCode | 3.x 新增的功能,在生产环境中支持 Mock |
# 4. 创建 Mock 数据
在 项目根目录(非src目录
) 下创建 mock/
目录,并在里面定义 Mock API。
# 创建 mock/user.ts
// 导入 mockjs
import Mock from 'mockjs';
// 模拟用户数据
function createUserList() {
return [
{
userId: 1,
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
username: 'admin',
password: '111111',
desc: '平台管理员',
roles: ['平台管理员'],
token: 'Admin-Token',
},
{
userId: 2,
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
username: 'system',
password: '111111',
desc: '系统管理员',
roles: ['系统管理员'],
token: 'System-Token',
},
];
}
export default [
// 用户登录接口
{
url: '/api/user/login',
method: 'post',
response: ({ body }) => {
const { username, password } = body;
const checkUser = createUserList().find(
(item) => item.username === username && item.password === password
);
if (!checkUser) {
return { code: 201, message: '账号或密码不正确' };
}
return { code: 200, data: { token: checkUser.token } };
},
},
// 获取用户信息
{
url: '/api/user/info',
method: 'get',
response: (request) => {
const token = request.headers.token;
const checkUser = createUserList().find((item) => item.token === token);
if (!checkUser) {
return { code: 201, message: '获取用户信息失败' };
}
return { code: 200, data: checkUser };
},
},
];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# 5. 安装 Axios 并测试 Mock API
为了测试 Mock 接口,我们需要安装 axios
进行请求。
pnpm install axios
# 封装 axios
请求
创建 src/utils/request.ts
:
import axios from 'axios';
const request = axios.create({
baseURL: '/api', // 统一设置 Base URL
timeout: 5000, // 设置超时时间
});
// 请求拦截器
request.interceptors.request.use(
(config) => {
config.headers.token = localStorage.getItem('token') || '';
return config;
},
(error) => {
return Promise.reject(error);
}
);
// 响应拦截器
request.interceptors.response.use(
(response) => {
if (response.data.code !== 200) {
return Promise.reject(response.data.message);
}
return response.data;
},
(error) => {
return Promise.reject(error);
}
);
export default request;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 6. 测试 Mock API
# 在 App.vue
组件中测试
<template>
<div>
<button @click="login">测试登录</button>
<button @click="getUserInfo">获取用户信息</button>
</div>
</template>
<script setup lang="ts">
import apiClient from '@/utils/request';
// 登录
const login = async () => {
try {
const res = await request.post('/user/login', {
username: 'admin',
password: '111111',
});
console.log('登录成功:', res);
localStorage.setItem('token', res.data.token);
} catch (error) {
console.error('登录失败:', error);
}
};
// 获取用户信息
const getUserInfo = async () => {
try {
const res = await request.get('/user/info');
console.log('用户信息:', res);
} catch (error) {
console.error('获取用户信息失败:', error);
}
};
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 7. Mock插件的原理
# mock 插件如何拦截 API?
vite-plugin-mock
插件的核心原理是:
- 拦截符合特定规则的 API 请求(例如
/api/user/login
)。 - 根据定义的响应规则,直接返回模拟数据。
- 不依赖
mockjs
,可以直接定义response
返回数据,而mockjs
主要用于生成随机数据。
📌 Vite 内置开发服务器
在 Vite 开发模式(vite dev
)下,vite-plugin-mock
会在 Vite 的开发服务器(Express 或 Koa)中注册一个中间件,在前端向 /api/xxx
发送请求时,Mock 插件会拦截该请求,并返回我们在 mock/
目录中定义的模拟数据。
📌 关键拦截逻辑
- 如果请求 URL 和
mock
目录中的url
规则匹配:vite-plugin-mock
拦截该请求,不再向真实后端发送。- 返回
response
中定义的模拟数据。
- 如果请求 URL 不匹配:
- Vite 不会拦截,请求会正常发送到后端 API。
# mock 插件是如何处理 API 拦截的?
vite-plugin-mock
不需要手动调用 Mock
API 拦截,它基于 Vite 的服务器拦截请求,拦截逻辑如下:
- 在
vite.config.ts
注册viteMockServe
,Vite 在启动时会加载 Mock 数据。 - 只要 Mock API 规则符合
export default [...]
这种数组格式,插件会自动读取和拦截。 - 当前端发送 API 请求时:
- 匹配 Mock API 规则 → 直接返回 Mock 数据。
- 不匹配 → 请求继续发送到真实后端。
📌 vite-plugin-mock
API 处理流程
前端发起 API 请求 ➝ Vite 开发服务器 ➝ vite-plugin-mock 检查是否匹配 Mock 规则
├── ✅ 匹配成功 ➝ 返回 `response` 模拟数据
├── ❌ 匹配失败 ➝ 继续向真实后端 API 发送请求
2
3
# 8. Vite Mock API 请求参数
在 vite-plugin-mock
插件中,前端请求 API 时,request
对象会包含所有请求相关的信息,包括:
body
(请求体)→ 适用于POST / PUT
query
(查询参数)→ 适用于GET
headers
(请求头)→ 适用于所有请求,如token
Mock API 需要通过这些参数解析前端传递的数据,并返回相应的 Mock 数据。
# 1. Vite Mock API 的 request
结构
在 vite-plugin-mock
插件的 response: (request) => {}
处理函数中,request
主要包含以下参数:
参数 | 适用请求方法 | 作用 |
---|---|---|
body | POST / PUT | 请求体数据(前端提交的 JSON 数据) |
query | GET | URL 查询参数(例如 /api/user/info?id=1 ) |
headers | 所有请求 | 请求头信息(例如 token ) |
当前端发送请求时,request
对象的结构示例如下:
{
body: { username: 'admin', password: '123456' }, // POST / PUT 请求的请求体
query: { id: '1' }, // GET 请求的 URL 参数
headers: { token: 'Admin-Token' }, // 请求头信息
}
2
3
4
5
# 2. Vite Mock API request
示例
# 📌 解析 POST
请求中的 body
对于 POST
请求,数据通常放在请求体 body
中:
{
url: '/api/user/login',
method: 'post',
response: ({ body }) => {
console.log('POST 请求体:', body);
const { username, password } = body;
if (username !== 'admin' || password !== '123456') {
return { code: 201, message: '账号或密码不正确' };
}
return { code: 200, message: '登录成功', data: { token: 'Admin-Token' } };
},
}
2
3
4
5
6
7
8
9
10
11
12
13
14
📌 前端调用示例
axios.post('/api/user/login', {
username: 'admin',
password: '123456',
});
2
3
4
📌 服务器接收的数据
{ body: { username: 'admin', password: '123456' } }
# 📌 解析 GET
请求中的 query
对于 GET
请求,数据通常放在 URL 参数中:
{
url: '/api/user/info',
method: 'get',
response: ({ query }) => {
console.log('GET 请求参数:', query);
const { id } = query;
if (!id) {
return { code: 400, message: '缺少 ID 参数' };
}
return { code: 200, message: '获取用户信息成功', data: { id, name: 'admin' } };
},
}
2
3
4
5
6
7
8
9
10
11
12
13
14
📌 前端调用示例
axios.get('/api/user/info?id=1');
📌 服务器接收的数据
{ query: { id: '1' } }
# 📌 解析 headers
通常用于获取 token
进行身份验证:
{
url: '/api/user/protected',
method: 'get',
response: ({ headers }) => {
console.log('请求头:', headers);
const token = headers.token;
if (token !== 'Admin-Token') {
return { code: 403, message: '无效的 Token' };
}
return { code: 200, message: '访问成功', data: { role: '管理员' } };
},
}
2
3
4
5
6
7
8
9
10
11
12
13
14
📌 前端调用示例
axios.get('/api/user/protected', {
headers: { token: 'Admin-Token' },
});
2
3
📌 服务器接收的数据
{ headers: { token: 'Admin-Token' } }
# 3. Vite Mock API 标准写法模板
下面是一个标准的 Mock API 结构,适用于所有 vite-plugin-mock
Mock API 编写。
export default [
// 示例接口
{
url: '/api/example', // 请求 URL
method: 'get' | 'post' | 'put' | 'delete', // 请求方法
timeout: 500, // 可选:模拟请求延迟(毫秒)
statusCode: 200, // 可选:模拟 HTTP 响应状态码
response: ({ body, query, headers }) => {
console.log('请求体:', body);
console.log('URL 参数:', query);
console.log('请求头:', headers);
return {
code: 200,
message: '请求成功',
data: {
key1: 'value1',
key2: 'value2',
},
};
},
},
];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 9. Vite Mock API 返回的数据结构
在 vite-plugin-mock
插件中,Mock API 返回的数据不会像 axios
那样自动包装一层,而是直接返回开发者定义的 response
数据。
# 1. vite-plugin-mock
返回的数据
在 vite-plugin-mock
插件中,Mock API 仅返回 response
处理函数中的数据:
export default [
{
url: '/api/user/info',
method: 'get',
response: () => {
return {
code: 200,
message: '成功',
data: { username: 'admin', role: '管理员' },
};
},
},
];
2
3
4
5
6
7
8
9
10
11
12
13
如果前端使用 fetch
或 axios
请求:
axios.get('/api/user/info').then((res) => {
console.log(res);
});
2
3
📌 实际返回数据
{
"code": 200,
"message": "成功",
"data": {
"username": "admin",
"role": "管理员"
}
}
2
3
4
5
6
7
8
✅ 结论:Vite Mock API 不会自动包装 status
、statusText
、headers
,它只返回 response
定义的数据。
# 2. axios
自动包装的 response
结构
相比之下,axios
会自动包装一层,在 axios.get()
的 response
结构中,会包含 status
、statusText
、headers
等:
{
"data": {
"code": 200,
"message": "成功",
"data": {
"username": "admin",
"role": "管理员"
}
},
"status": 200,
"statusText": "OK",
"headers": { /* 服务器返回的响应头 */ },
"config": { /* axios 配置信息 */ },
"request": { /* 请求对象 */ }
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
📌 说明
data
:Vite Mock API 真正返回的 JSON 数据(即response
中定义的数据)。status
/statusText
:HTTP 状态码和文本,axios
会自动补充。headers
:服务器返回的 HTTP 响应头。
# 3. 让 Vite Mock API 也返回 HTTP 状态
如果我们希望 Mock API 也能模拟 axios
响应的完整结构,可以手动在 response
中包装:
export default [
{
url: '/api/user/info',
method: 'get',
response: () => {
return {
data: {
code: 200,
message: '成功',
data: { username: 'admin', role: '管理员' },
},
status: 200,
statusText: 'OK',
headers: { 'Content-Type': 'application/json' },
};
},
},
];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
📌 这样 axios
返回的 response.data
结构就和真实服务器一致:
{
"data": {
"code": 200,
"message": "成功",
"data": {
"username": "admin",
"role": "管理员"
}
},
"status": 200,
"statusText": "OK",
"headers": { "Content-Type": "application/json" }
}
2
3
4
5
6
7
8
9
10
11
12
13
# 4. 统一封装 axios
,处理 Mock API 响应
如果不想修改 Mock API,可以在 axios
封装时统一处理:
import axios from 'axios';
const request = axios.create({
baseURL: '/api',
timeout: 5000,
});
// 处理 `axios` 响应格式,兼容 Mock API
request.interceptors.response.use(
(response) => {
const resData = response.data;
return {
data: resData.data,
status: resData.code === 200 ? 200 : 400,
statusText: resData.message || 'OK',
headers: response.headers,
};
},
(error) => {
return Promise.reject(error);
}
);
export default request;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
📌 这样,即使 vite-plugin-mock
只返回 code/message/data
,前端 axios
依然能解析成标准格式。
结论
✅ Vite Mock API 仅返回 response
定义的数据,不会自动添加 status
、headers
。
✅ axios
会自动包装一层,包括 status
、headers
等信息。
✅ 如果需要完整的 HTTP 响应结构,可以:
- 在 Mock API
response
里手动补充status
、headers
。 - 在
axios
拦截器中统一处理 Mock API 的数据格式。
这样,我们的 axios
代码可以兼容 Mock API 和真实服务器,提升开发体验 🚀!