作前端的应该都知道作页面的时候,当后端已经定义好了接口,但提供不了数据服务的时候,做为前端的你搭建页面是很痛苦的。 为此搭建一个能够mock数据的本地服务是颇有必要的。前端
用到的工具库:json-server提供服务。mockjs提供模拟的数据。node
本文的目录结构以下:webpack
一、安装依赖web
npm install json-server mockjs --D
复制代码
二、编写db.json路由对应表npm
这是一个api路径和路径对应返回的内容组成的一个文件,好比:json
{
"user_info": {
"id": 1000,
"course_name": "马连白米且",
"autor": "袁明",
"college": "金并即总变史",
"category_Id": 2
}
}
复制代码
上面的user_info就是你的api接口路径,后面的value值就是这个接口返回的内容.后端
假如你本地起了一个json-server服务,http://localhost:6666,api
那么你访问http://localhost:6666/user_info获得的就是如下内容:数组
{
"id": 1000,
"course_name": "马连白米且",
"autor": "袁明",
"college": "金并即总变史",
"category_Id": 2
}
复制代码
但问题来了: 这样简单的定义一个db.json文件,你每次访问http://localhost:6666/user_info的时候,获得的都是同一份数据,它不会变。 这不是咱们想要的效果。咱们想要每次访问都获得不同的数据。bash
mock/mockDB/test.js
// 引入mock.js
let Mock = require('mockjs');
let Random = Mock.Random;
// 编写一个函数,这个函数利用mock.js动态生成mock数据
// 我看到不少教程这里是直接输出一个对象的,这样每次访问获得的都是一样的数据。不符合预期,
// 咱们这里用函数包装,每次访问api的时候就执行一次该函数,获得的就是新的mock数据了
function testList() {
const monitorList = [];
for (var i = 0; i < 3; i++) {
monitorList.push(
Mock.mock({
userid: '25788869998_1562054852076593528',
appid: Random.natural(100, 3000),
content: Random.cparagraph(2, 4),
timestamp: 1562054852,
})
);
}
// 这里返回你想要的数据格式
return {
success: true,
data: monitorList,
message: '获取数据成功',
};
}
// 以api路径为值,将testList函数暴露出去
exports.user_info = testList;
复制代码
如上文所说,json-server须要一个json文件作路由配置表,格式以下:
{
"user_info": {
"id": 1000,
"course_name": "马连白米且",
"autor": "袁明",
"college": "金并即总变史",
"category_Id": 2
}
}
复制代码
很是注意的是: 路由配置里,api路径为key值,返回的数据为value值,这个value必须是数组或者对象。不能是函数,下面的写法是会报错的。
{
"user_info": function () {
return {
"id": 1000,
"course_name": "马连白米且",
}
}
}
复制代码
但想要每次请求同一个接口,返回的都是不同的数据,这个value必须是函数才行。这就是咱们在mock/mockDB/test.js定义的是函数的缘由。由于json-server的原理应该是:拿到访问的路径,而后经过路由配置表找到对应的value值,最后返回给用户的。若是写死成一个对象,或者数组,那么每次访问获得的都是一样的数据。
mock/db.js
将mockDB文件夹全部的mock数据文件读取出来,组装成上面路由配置表的格式,再暴露出去。 这里能够用webpack提供的require.context读取全部文件,也能够用node的fs模块读取全部文件。这里我就不展开来写了。简单说一下流程。
// 引入mockDB文件夹下的文件,假若有如下文件
let test1 = require('./mockDB/test.js');
let test2 = require('./mockDB/test2.js');
// 这里定义一个收集的对象
let dbJson = {
func: {},
json: {},
}
// 收集mock函数,在server.js会用到
dbJson.func = {
...test1,
...test2,
};
// 获取全部的api路径
let apiPath = Object.keys(dbJson.func);
// 组装json-server须要的路由表,这里为何都是空对象呢?
// 上面说过,路由表的value必须是对象或者数组。但咱们的mockDB文件夹下定义的都是mock函数,因此这里要保证路由表是正确的,就要从新组装一份符合格式的路由表。
apiPath.forEach(item => {
dbJson.json[item] = {};
});
exports.dbJson = dbJson.json;
exports.dbFunc = dbJson.func;
复制代码
const jsonServer = require('json-server');
// 建立json-server实例
const server = jsonServer.create();
const jsonDB = require('./db');
// 将路由配置表传入,生成路由表
const router = jsonServer.router(jsonDB.dbJson);
const middlewares = jsonServer.defaults();
// 这里比较重要。
// 目的是:从新定义路由返回的数据。就是说:每访问一个路由,返回response的时候,均可以通过router.render从新定义response数据
// 由于咱们在db.js里将mock函数收集到了dbJson.func对象里。
router.render = (req, res) => {
// 根据请求的url,截取路径。
// 例如:通常状况,res.url是/user_info?id=1234这样的格式。
let end = req.url.indexOf('?');
let apiName = req.url.slice(1, end) || '';
// 根据apiName拿到对应的mock函数,而后返回mock函数生产的mock数据
// 由于每次返回response的时候,都会执行一次该函数,因此获得的都是新的mock数据
let response = dbJson.func[apiName] && dbJson.func[apiName]();
res.send(response || {}));
};
server.use(middlewares);
// 导入路由
server.use(router);
// 在6666端口开服务
server.listen(6666, () => {
console.log('JSON Server is running');
});
复制代码
node mock/server.js
复制代码
这篇文章是我的的实践作法,若是有说的不对的地方,还望见谅、指正,谢谢