读取模拟服务器的静态数据,读取模拟服务器动态数据。
一、准备工作
1、参考文档
json-server官网
mockjs官网
2、安装包
# 安装json-server服务
npm install json-server --save-dev
# 安装nodemon,修改配置无需重启服务
npm install nodemon --save-dev
# 安装批量生成数据
npm install mockjs --save-dev
3、mock目录结构
|--dynamic //动态数据方式
|--config.js //配置文件
|--db.js //动态数据文件
|--routes.js //路由规则
|--server.js //服务文件
|--static //静态数据方式
|--config.js //配置文件
|--db.js //静态数据文件
|--routes.js //路由规则
|--server.js //服务文件
4、给package.json添加配置
"scripts": {
"server": "cd mock/static && nodemon server.js",
"dserver": "cd mock/dynamic && nodemon server.js"
}
5、webpack配置(代理,接口路由匹配)
// 本地开发 Server 配置
const DEV_SERVER_CONFIG = {
historyApiFallback: true,
hot: true,
inline: true,
progress: true,
host: '127.0.0.1',
open: true,
overlay: true,
proxy: {
'/api/*': { // 静态
target: 'http://127.0.0.1:3005',
secure: true,
changeOrigin: true
},
/*'/api/*': { // 动态
target: 'http://127.0.0.1:3003',
secure: true,
changeOrigin: true
}*/
}
};
二、模拟从服务器读取数据-静态数据
1、文件调用依赖结构图
2、mock配置文件
// config.js
module.exports = {
SERVER: '127.0.0.1',
//定义端口号
PORT: 3005
};
// db.js
/**
* 数据模块
* 目标是把不同页面的变量和数据之间的映射集合到一个对象。
* 某页面
{
getList: { message: null, data: [Array], success: true, all: 3 },
deleteItem: { message: null, data: null, success: true, all: 0 }
}
* 大集合
{
getList: { message: null, data: [Array], success: true, all: 3 },
deleteItem: { message: null, data: null, success: true, all: 0 }
}
*/
// 引入需要mock数据的页面接口配置
let demoA = require('../../demos/staticDataA/fakeData/index.js');
let demoB = require('../../demos/staticDataB/fakeData/index.js');
const dataMaps = [demoA, demoB];
const mergeObject = (dMaps = []) => {
return Object.assign(...dMaps);
};
const dataObj = mergeObject(dataMaps);
module.exports = dataObj;
// routes.js
/**
* 路由模块
* 目标是把变量和接口地址之间的映射转换成路由映射表
* 变量和接口地址间的映射
{
api: {
getList: 'api/list',
deleteItem: 'api/delete'
}
};
* 路由映射表
{ '/api/list*': '/getList',
'/api/delete*': '/deleteItem'
}
*/
// 引入需要mock数据的页面接口配置
let demoA = require('../../demos/staticDataA/interfaceUrl.js');
let demoB = require('../../demos/staticDataB/interfaceUrl.js');
const interfaceMaps = [demoA, demoB];
const swapKeyValue = (iMaps = []) => {
return iMaps.reduce((previousValue, currentValue) => {
// 解构出api里面的配置
let { api } = currentValue;
for (let key in api) {
// key和value对调
previousValue[`/${api[key]}*`] = `/${key}`;
}
return previousValue;
}, {});
};
const routeMap = swapKeyValue(interfaceMaps);
module.exports = routeMap;
// server.js
const config = require('./config.js');
const jsonServer = require('json-server');
const rules = require('./routes.js');
const dbfile = require('./db.js');
const ip = config.SERVER;
const port = config.PORT;
const server = jsonServer.create();
const router = jsonServer.router(dbfile);
const rewriter = jsonServer.rewriter(rules);
const middlewares = jsonServer.defaults();
server.use(jsonServer.bodyParser);
server.use(middlewares);
// 添加响应头
server.use((req, res, next) => {
res.header('X-Server', 'jsonServer-mockjs');
next();
});
server.use(rewriter);
server.use(router);
server.listen({
host: ip,
port: port
}, function() {
console.log(JSON.stringify(jsonServer));
console.log(`JSON Server is running in http://${ip}:${port}`);
});
3、页面模块
// 目录树
│ ├── staticDataA
│ │ ├── fakeData
│ │ │ ├── deleteItem.js
│ │ │ ├── getList.js
│ │ │ └── index.js
│ │ ├── interfaceUrl.js
│ │ └── staticDataA.jsx
│ └── staticDataB
│ ├── fakeData
│ │ ├── getBookList.js
│ │ ├── index.js
│ │ └── updateItem.js
│ ├── interfaceUrl.js
│ └── staticDataB.jsx
// getList.js
module.exports = function() {
return {
'success': true,
'data': [{
'id': '001',
'name': 'banana'
},
{
'id': '002',
'name': 'orange'
},
{
'id': '003',
'name': 'apple'
}
]
};
};
// index.js
let getList = require('./getList.js');
let deleteItem = require('./deleteItem.js');
module.exports = {
getList: getList(),
deleteItem: deleteItem()
};
// interfaceUrl.js
// 既用于本地模拟接口,也用于读取真正的后端接口。
module.exports = {
api: {
getList: 'api/list',
deleteItem: 'api/delete'
}
};
4、启动页面和服务(记得切换webpack的代理配置)
# 启动服务
npm run server
npm run dev
打开浏览器,在地址栏中输入http://localhost:3005/
三、模拟从服务器读取数据-动态数据
1、mock配置文件
// config.js
module.exports = {
SERVER:"127.0.0.1",
//定义端口号
PORT: 3003
};
// db.js
/**
* 数据模块
* 目标是把不同页面的变量和数据之间的映射集合到一个对象。
* 某页面
{
getList: { message: null, data: [Array], success: true, all: 3 },
deleteItem: { message: null, data: null, success: true, all: 0 }
}
* 大集合
{
getList: { message: null, data: [Array], success: true, all: 3 },
deleteItem: { message: null, data: null, success: true, all: 0 }
}
*/
// 引入需要mock数据的页面接口配置
let demoA = require('../../demos/dynamicDataA/fakeData/index.js');
let demoB = require('../../demos/dynamicDataB/fakeData/index.js');
const dataMaps = [demoA, demoB];
const mergeObject = (dMaps = []) => {
return Object.assign(...dMaps);
};
const dataObj = mergeObject(dataMaps);
module.exports = dataObj;
// routes.js
/**
* 路由模块
* 目标是把变量和接口地址之间的映射转换成路由映射表
* 变量和接口地址间的映射
{
api: {
getList: 'api/list',
deleteItem: 'api/delete'
}
};
* 路由映射表
{ '/api/list*': '/getList',
'/api/delete*': '/deleteItem'
}
*/
// 引入需要mock数据的页面接口配置
let demoA = require('../../demos/dynamicDataA/interfaceUrl.js');
let demoB = require('../../demos/dynamicDataB/interfaceUrl.js');
const interfaceMaps = [demoA, demoB];
const swapKeyValue = (iMaps = []) => {
return iMaps.reduce((previousValue, currentValue) => {
// 解构出api里面的配置
let { api } = currentValue;
for (let key in api) {
// key和value对调
previousValue[`/${api[key]}*`] = `/${key}`;
}
return previousValue;
}, {});
};
const routeMap = swapKeyValue(interfaceMaps);
module.exports = routeMap;
// server.js
const config = require('./config.js');
const jsonServer = require('json-server');
const rules = require('./routes.js');
const dbfile = require('./db.js');
const ip = config.SERVER;
const port = config.PORT;
const server = jsonServer.create();
const router = jsonServer.router(dbfile);
const rewriter = jsonServer.rewriter(rules);
const middlewares = jsonServer.defaults();
server.use(jsonServer.bodyParser);
server.use(middlewares);
// 添加响应头
server.use((req, res, next) => {
res.header('X-Server', 'jsonServer-mockjs');
next();
});
server.use(rewriter);
server.use(router);
server.listen({
host: ip,
port: port
}, function() {
console.log(JSON.stringify(jsonServer));
console.log(`JSON Server is running in http://${ip}:${port}`);
});
2、页面模块
// 目录树
├── demos
│ ├── dynamicDataA
│ │ ├── dynamicDataA.jsx
│ │ ├── fakeData
│ │ │ ├── getNewsA.js
│ │ │ └── index.js
│ │ └── interfaceUrl.js
│ ├── dynamicDataB
│ │ ├── dynamicDataB.jsx
│ │ ├── fakeData
│ │ │ ├── getNewsB.js
│ │ │ └── index.js
│ │ └── interfaceUrl.js
// getNewsA.js
let Mock = require('mockjs');
let Random = Mock.Random;
module.exports = function() {
var data = {
news: []
};
for (var i = 0; i < 10; i++) {
var content = Random.cparagraph(0, 10);
data.news.push({
id: i,
title: Random.cword(8, 20),
desc: content.substr(0, 40)
});
}
return {
'success': true,
'data': data
};
};
// index.js
let getNewsA = require('./getNewsA.js');
module.exports = {
getNewsA: getNewsA()
};
// interfaceUrl.js
// 既用于本地模拟接口,也用于读取真正的后端接口。
module.exports = {
api: {
getNewsA: 'api/newsListA'
}
};
3、启动服务和页面
# 启动服务
npm run dserver
npm run dev
打开浏览器,在地址栏中输入http://localhost:3003/
四、规范制度
本着少踩坑的原则,下面约束一些fakeData中的开发规范。
1、mock多模块,文件命名应该不一致。
比如A模块是staticDataA/fakeData/getList.js,B模块是staticDataB/fakeData/getBookList.js。
2、不同模块,key命名要不同。
比如A模块是demos/staticDataA/fakeData/index.js,key有getList和deleteItem。
比如B模块是demos/staticDataB/fakeData/index.js,key有getBookList和updateItem。
3、文件名和变量名保持一致
比如 let getList = require('./getList.js');
4、同一模块,key命名要一致。
比如A模块的staticDataA/fakeData/index.js文件的key为getList,staticDataA/interfaceUrl.js文件的key为getList,也就是说数据映射变量和路由映射变量需要保持一致。