在前端开发中,有时候会需要mock接口,虽然有的工具提供了云端mock的功能,但是定制化比较低,所以我用node写了一个mock小工具,主要使用了express、mockjs、cors,
"cors": "^2.8.5",
"express": "^4.19.2",
"mockjs": "^1.1.0"
使用两个文件即可完成这个小功能
首先搭建一个简单的后端服务,这里使用express
server.js :
const express = require('express');
const Mock = require('mockjs');
const app = express();
const port = 3000;
const generateMockTemplate = require('./generateJson.js')
var cors = require('cors')
app.use(cors())
app.post('/mty/mtyOll', (req, res) => {
const userData = Mock.mock(JSON.parse(generateMockTemplate(
// json放这里----------------------------------------------------------
{
"msg": "",
"code": "",
"data": [
{
"id": "",
"userId": "",
"intCls": 0,
"intClsName": "",
"applicant": "",
"applicantType": 0,
"applicantAddress": "",
"brandApplicantNum": 0,
"brandRegNum": 0,
}
]
}
// json放这上边----------------------------------------------------------
)));
res.json(userData);
});
// 或者,如果你想要根据请求参数动态生成数据
app.get('/api/example', (req, res) => {
const userId = parseInt(req.params.id, 10);
// 假设我们只返回一个用户,根据ID随机匹配或生成
const user = Mock.mock({
'id': userId,
'name': '@cname',
'age|18-60': 1,
'city': '@city(true)',
'email': '@EMAIL'
});
res.json(user);
});
// 启动服务器
app.listen(port, () => {
console.log(`Mock server running at http://localhost:${port}/`);
});
接下来,使用需要接入Mock,mock规则通过Mock.mock来控制,Mock.mock用来记录数据模板。当拦截到匹配 rurl 的 Ajax 请求时,将根据数据模板 template 生成模拟数据,并作为响应数据返回。
接下来就是在generateJson.js中配置自己个性化的数据返回了,具体规则可以参考mockjs文档
generateJson.js:
const Mock = require('mockjs');
function generateMockTemplate(json) {
let first = true
function processValue(value, itemKey) {
// 特性适配
if (itemKey === 'code') {
if (first) {
first = false;
return '"00000"'; //第一个字段固定值
} else {
return '"@integer(0, 8)"';
}
} else if (
itemKey.indexOf('num') > -1 ||
itemKey.indexOf('Num') > -1 ||
itemKey.indexOf('int') > -1 ||
itemKey.indexOf('Int') > -1) {
return '"@integer(0, 10)"';
} else if (
itemKey === 'current' ||
itemKey === 'total' ||
itemKey === 'maxTotal' ||
itemKey === 'size' ||
itemKey === 'pages') {
return '"@integer(60, 1000)"'
} else if (
itemKey.indexOf('Color') > -1 ||
itemKey.indexOf('color') > -1) {
return `"@color"`
} else if (itemKey.indexOf('Name') > -1) {
return `"@cword(5,10)"`
} else if (
itemKey.indexOf('Price') > -1 ||
itemKey.indexOf('price') > -1) {
return `"@natural(2000, 100000)"`
} else if (itemKey.indexOf('word') > -1) {
return '"@cword(5,20)"';
} else if (
itemKey.indexOf('Status') > -1 ||
itemKey.indexOf('status') > -1 ||
itemKey.indexOf('key') > -1 ||
itemKey.indexOf('Key') > -1||
itemKey.indexOf('type') > -1 ||
itemKey.indexOf('Type') > -1) {
return `"@integer(0, ${value?value:4})"` //可以在模板json中设置最大值
} else if (
itemKey.indexOf('Time') > -1 ||
itemKey.indexOf('Date') > -1) {
return `"@datetime()"`
} else if (
itemKey.indexOf('id') > -1 ||
itemKey.indexOf('Id') > -1 ||
itemKey.indexOf('code') > -1 ||
itemKey.indexOf('Code') > -1||
itemKey.indexOf('No') > -1 ||
itemKey.indexOf('no') > -1) {
return `"@guid"`
} else if (
itemKey.indexOf('url') > -1 ||
itemKey.indexOf('Url') > -1 ||
itemKey.indexOf('image') > -1 ||
itemKey.indexOf('Image') > -1 ||
itemKey.indexOf('File') > -1 ||
itemKey.indexOf('file') > -1) {
return '"@url()"';
} else if (itemKey.indexOf('En') > -1) {
return '"@title(3, 5)"';
} else if (
itemKey.indexOf('Phone') > -1 ||
itemKey.indexOf('phone') > -1) {
return Array.from({
length: 11
}, () => Mock.Random.pick(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'])).join('');
}
if (typeof value === 'string') {
return '"@cword(5,20)"';
} else if (typeof value === 'number') {
// 假设数字可能是一个范围
return `"@integer(0, 10)"`;
// return `"@integer(${Math.floor(value * 0.8)}, ${Math.ceil(value * 12)})"`; // 生成接近原数字但有一定范围的随机整数
} else if (typeof value === 'boolean') {
// 布尔值直接返回
return `${value}`;
} else if (Array.isArray(value)) {
// 数组需要递归处理每个元素,并确定数组长度
if (value.length === 0) {
return '[]'; // 空数组直接返回
}
const elementTemplate = processValue(value[0], ''); // 假设所有元素类型相同,只取第一个元素作为模板
return `|${value.length}-${value.length+10}":[${elementTemplate}]`; // 数组长度固定,元素类型相同
} else if (typeof value === 'object' && value !== null) {
// 对象需要递归处理每个属性
let properties = Object.keys(value).map(key => {
const processedValue = processValue(value[key], key);
return `"${key}":${processedValue}`;
}).join(',');
return `{${properties}}`;
} else {
// 其他类型(如null、undefined、function等)可能需要根据实际情况处理
// 这里简单处理为null
return 'null';
}
}
const template = processValue(json, '').split('":|').join('|');
return template;
}
module.exports = generateMockTemplate;
这样,后端服务就ok了,node启动server.js即可运行,我这里使用的是3000端口
接下来,在前端服务配置下代理即可使用:
- vue.config.js 中添加如下配置:
"^/mock/": {
target: "http://localhost:3000",
changeOrigin: true,
pathRewrite: {
"^/mock/": ""
}
}
- 在api接口中添加配置如下(基于本项目内容):
let mock = '/mock';
export const getCouponInfoById = (params) => {
return request.post(mock + '/mty/mtyOll', params)
}
- 注意api配置文件中/mty/mtyOll内容与后端服务中server.js填的接口名要相同,代理中的端口号要相同