关联标签: #vue #vite #mock #yapi #easymock #前端
背景
项目启动前期,后端同学只提供了接口文档,前端同学为了使功能流程跑通,需要根据文档去 mock 数据。
技术调研
如何优雅的 mock 数据,是通过云端平台 yapi、easy-mock,还是本地 mock 方案。目前使用个人搭建的 easy-mock 服务。
EasyMock
- 官网:easy-mock/easy-mock at master (github.com)
- 优点:
- 支持内网部署
- 支持接口代理
- 支持 Swagger && OpenAPI 导入
- 支持 Mock.js 语法
- 支持 restc 接口预览
- 支持自定义响应配置
- 支持团队管理
- 缺点:
- 不支持文档
- 云端部署
YApi
- 官网:github.com/ymfe/yapi
- 优点:
- 支持内网部署
- 支持自动化测试
- 支持类似 postman 接口调试
- 扁平化权限管理
- 支持 Mock.js 语法
- 支持自定义插件
- 支持参数和响应格式预览
- 缺点:
- 需要云端部署
本地 mock
- 官网:Mock.js (mockjs.com)
- 优点:
- 跟随项目代码
- 支持 js 语法,可随意定制请求和响应
- 可跟随 git,有版本控制
- 缺点
- 项目外的人员无法查看
项目实践
目前个人使用 easy-mock 搭建云端服务,比较繁琐的事情是没有部署到公司里,无法将后端的 swagger 文档给同步过来,最后还是决定采用本地 mock 方案,将 mock 代码放入项目 git 仓库,每个人去开发自己功能的时候,自己创建个人的 mock 文件。
安装依赖
目前团队项目使用 vue 框架 2.x 版本,vite 2.x 版本构建,pnpm 进行包管理。
需要再命令行中安装如下依赖
# mockjs 用于生成 mock 数据
# vite-plugin-mock 是 vite 的插件
pnpm i mockjs vite-plugin-mock -D
项目配置
更新 vite.config.js
import { createVuePlugin } from 'vite-plugin-vue2';
import { viteMockServe } from 'vite-plugin-mock';
// https://vitejs.dev/config/
export default ({ command }) => {
console.log('current command is ', command);
return {
resolve: {
alias: [{ find: '@', replacement: '/src' }],
},
css: {
preprocessorOptions: {
scss: {
additionalData: `@import "@/assets/style/index.scss";`,
},
},
},
plugins: [
createVuePlugin(),
viteMockServe({
ignore: /^\_/, // 以 _ 开头的是工具文件,忽略
mockPath: 'mock', // 存放在 mock 目录下
prodEnabled: false, // 关闭生产环境 mock
}),
],
};
};
项目根目录创建 mock 文件夹,同时创建 mock/_utils.ts 工具方法文件
// 成功响应
export function success<T = Recordable>(data: T, msg = 'success') {
return {
code: 0,
data,
msg,
};
}
// 列表成功响应
export function listSuccess<T = any>(
page: number,
limit: number,
list: T[],
{ msg = 'success' } = {}
) {
const pageData = pagination(page, limit, list);
return {
...success({
list: pageData,
total: list.length,
}),
msg,
};
}
// 错误响应,错误码前2位为业务分类,后4位为业务内部错误
// 1 开头的错误为网关错误和通用认证错误,业务侧不得声明为 1 开头的错误码
export function fail(msg = 'mock 错误', code = 100000, data = null) {
return {
code,
data,
msg,
};
}
// 分页方法
export function pagination<T = any>(
page: number,
limit: number,
list: T[]
): T[] {
const offset = (page - 1) * Number(limit);
const ret =
offset + Number(limit) >= list.length
? list.slice(offset, list.length)
: list.slice(offset, offset + Number(limit));
return ret;
}
// 请求参数类型
export interface requestParams {
method: string;
body: any;
headers?: { authorization?: string };
query: any;
}
// 获取请求头认证 token
export function getRequestToken({
headers,
}: requestParams): string | undefined {
return headers?.authorization;
}
创建 mock/demo.ts 文件,mock 一个增删改查的接口
import { MockMethod } from 'vite-plugin-mock';
import Mock from 'mockjs';
import { success, fail, listSuccess, requestParams } from '../_utils.ts';
// 自定义手机号 mock
Mock.Random.extend({
phone() {
return Mock.mock(/1[3456789]\d{9}/);
},
});
export default [
// 创建
{
url: '/demos/create',
timeout: 1000,
method: 'post',
response({ body }) {
return success({
id: 123,
createdAt: '@now',
updatedAt: '@now',
...body,
});
},
},
// 删除
{
url: '/demos/delete',
timeout: 1000,
method: 'delete',
response({ query }) {
if (parseInt(query.id) === 1) {
return fail('内容不存在');
}
return success(null, '删除成功');
},
},
// 修改
{
url: '/demos/update',
timeout: 1000,
method: 'put',
response({ query, body }) {
return success({
...body,
id: query.id,
updatedAt: '@now',
});
},
},
// 查询列表
{
url: '/demos/list',
timeout: 1000,
method: 'get',
response({ query }: requestParams) {
const res: any = [];
for (let i = 0; i < 88; i++) {
res.push({
id: i + 1,
'type|1': ['管理员', '白名单'],
'userId|100000-200000': 100,
username: '@cname()',
createdAt: '@datetime',
updatedAt: '@now',
});
}
return listSuccess(query.page, query.limit, res);
},
},
// 查询详情
{
url: '/demos/detail',
timeout: 1000,
method: 'get',
response({ query }) {
return success({
id: parseInt(query.id),
name: '@cname',
email: '@email',
bio: '@cparagraph',
phone: Mock.Random.phone(),
createdAt: '@datetime',
updatedAt: '@now',
});
},
},
] as MockMethod[];
效果演示
总结
目前团队前端项目和后端项目相对独立,没有串联,因此采用本地 Mock 的方式可以低成本、高定制化、高效的解决前端对接口依赖的问题。
相对于大型团队的项目来讲,如果公司的基础设施完善,那么可以优先考虑部署可定制化更高的 YApi 进行接口管理,将文档和其他工具流串联打通起来,从后端开始创建 Swagger → YApi → 前端 Mock → 测试接口自动化 → 产品查阅接口文档,当整个链路全部打通,创建标准化开发流程,会大大提高研发效率,降低因接口产生的沟通成本。