前端模拟数据的技术方案(二)

读取模拟服务器的静态数据,读取模拟服务器动态数据。

一、准备工作

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、文件调用依赖结构图

前端模拟数据的技术方案(二)_第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,也就是说数据映射变量和路由映射变量需要保持一致。

前端模拟数据的技术方案(二)_第2张图片

转载于:https://www.cnblogs.com/camille666/p/fe_fake_data_server.html

你可能感兴趣的:(前端模拟数据的技术方案(二))