流年似水博客开通了,本站主要是写关于Web和大数据方面内容,正在更新中,欢迎大家光临!
  1. 文章:97 篇
  2. 总浏览:54,211 次
  3. 评论:22条
  4. 最后更新:2020-06-08
  5. 分类目录:39 个

前端工程化-搭建本地 Mock 服务

前端工程化 l, xy 510℃ 0评论

前言:

  前后端分离的协作模式下,前后端数据传输都是基于http接口实现的显然前端的开发是依赖后端接口实现的。在讲求快速迭代的互联网公司这种串行的等待肯定是不会出现的。前后端约定好接口的出参和入参之后,前端数据模拟(mock)就很有必要了。前端基于接口文档自己模拟一份假数据作为前端的数据源。后端按照约定的文档实现接口功能。

MOCK文档 readme

mock实现有几种方式:

  1. 在前端项目写死本地数据
  2. 前端项目中建立mock文件,随机生成参数
  3. Mock Server 的方式进行数据模拟

一、在前端项目写死本地数据:

在前端写死数据,是最简单的实现方式,前端通常将某个接口的动作封装到一个方法里,调用的时候直接返回写死的数据。

async getData(){
       // 开发阶段不走接口直接返回本地mock数据。
       return await new Promise(function(resolve){
           setTimeout(()=>{
               resolve({code:0, message: 'success', data: {}})
            }, 200)
       })
       // 真实的请求
       return await axios.get('/api/getUserInfo');
 }

这种方法在接口比较少的情况下,使用会比较合适,不然大量的json数据定义,很麻烦!

二、前端项目中建立mock文件,使用mock随机生成参数

1、安装mockjs

    使用npm安装:npm install mockjs;

    或直接<script src="http://mockjs.com/dist/mock.js"></script>;

2、在根目录下新建mock文件夹,在mock文件夹下新建util.js

- mockDom/
-   mock/
-     util.js

3、编辑util.js

const Mock = require("mockjs");
let data = Mock.mock({
    "data|10": [ //生成100条数据 数组
        {
            "id|+1": 1, //生成商品id,自增1
            "detail": "@ctitle(10)", //生成商品信息,长度为10个汉字
            "name": "@cname", //生成商品名 , 都是中国人的名字
            "phone": /^1(5|3|7|8)[0-9]{9}$/, //生成随机电话号
            "price|30-1000": 30, //随机生成商品价格 在30-1000之间
            "img": "@Image(‘100x40‘,‘#c33‘, ‘#ffffff‘,‘小北鼻‘)", //生成随机图片,大小/背景色/字体颜色/文字信息
        }
    ]
})
Mock.mock(/goods\/goodAll/, 'post', () => { //三个参数。第一个路径,第二个请求方式post/get,第三个回调,返回值
    return data
})

4、模拟完数据后,需要在入口主文件 entry.js中 引入这个模拟数据的文件

// 引入配置好的mockjs
import '../mock/util.js';

5、页面调用接口(这里为了便捷,使用axios调用,但是你也可以用ajax调用)

import axios from "axios";
mounted: () {
   this.initData();
},
methods:{
   initData(){
    axios.post("http://localhost:8080/goods/goodAll").then((res)=>{
     console.log(res)
    })
   }
}

三、Mock Server 的方式进行数据模拟

我们为什么选择这种方式?

拦截请求替换成我们准备好的mock数据,这样做对我们代码无侵入型,缺点就是配置繁琐,不便于复用。

Mock Server实现需要3部分node服务、路由、数据模拟

1、第一步使用express搭建node项目

执行语句:

npm init  

一直回车键即可,生成package.json

2、第二步配置express及路由

在根目录下新建index.js

-mockServer/
-   index.js
-   package.json

下载: express

npm i express -S

编辑index.js

var express = require('express');
var app = express();  
app.get('/', function(req, res) { res.send('Hello World!'); });
var server = app.listen(3000, function() {
    var host = server.address().address;
    var port = server.address().port; 
    console.log('Example app listening at http://%s:%s', host, port);
});

控制台运行:

node index.js

3、第三步,写死数据模拟接口

在根目录下,新建mock文件夹和server.js文件

-mockServer/
-   mock/
-     server.js
-   index.js
-   package.json

执行下载所需包:

npm i body-parser connect-multiparty -S

编辑server.js

const express = require("express");
const bodyParser = require("body-parser");
const multipart = require("connect-multiparty");

const multipartMiddleware = multipart();
const app = express();

// 定义mock方法
const mock = (data, params) => {
    if (Object.prototype.toString.call(data) === "[object Object]") {
        return data;
    } else if (typeof data === "function") {
        return data(params);
    } else {
        return "error: data shold be an object or a function.";
    }
};

// mock数据
const getUserInfo = {
    code: 0,
    message: "success",
    data: {
        name: "Alice",
        mobile: "182xxxx9999",
        age: 30
    }
}
const testData = {
    code: 0,
    message: "success",
    data: {
        id: 1,
        name: "test"
    }
}

// 路由和数据的聚合
const config = [{
    method: "get",
    url: '/api/getUserInfo',
    data: getUserInfo
}, {
    method: "post",
    url: '/api/test',
    data: getUserInfo
}];

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// 绑定路由信息
config.forEach(({ method, url, data }) => {
    if (method === "get") {
        app.get(url, (req, res) => {
            res.json(mock(data, req.query));
        });
    } else if (method === "post") {
        app.post(url, multipartMiddleware, (req, res) => {
            res.json(mock(data, req.body));
        });
    } else if (method === "jsonp") {
        app.get(url, (req, res) => {
            const query = req.query;

            const mockData = JSON.stringify(mock(data, req.query));
            const callback =
                "typeof " +
                query.callback +
                ' === "function" && ' +
                query.callback +
                "(" +
                mockData +
                ")";

            res.send(callback);
        });
    }
});

// 支持自定义端口
let port = 8081;
process.argv.forEach((arg, index, arr) => {
    console.log("arg----------", arg);
    if (arg === "--port") {
        port = arr[index + 1] || 8081;
        return false;
    }
});

module.exports = app.listen(port, () => {
    console.log("Mock Server listening on http://localhost:" + port);
});

引入到index.js(需要将index.js文件清空,避免冲突)

var server = require("./mock/server.js")

运行项目:

node index.js

浏览器访问:http://localhost:8081/api/getUserInfo ,能访问到数据说明我们的接口已经写好了,在你的前端项目调用即可。

4、第四步使用 Mock.js 造假数据,拆分模块

下载mockjs

$  npm i mockjs -S

mock下面添加api文件夹

-mockServer/
-   mock/
-     config.js
-     server.js
-     api/
-       getUserInfo.js
-       testData.js
-   index.js
-   package.json

最终文件代码:

getUserInfo.js

module.exports = {
    "code": 0,
    "message": "success",
    "data": {
        "name": "@cname",
        "mobile": /^1[385]\d{9}$/,
        "age|18-50": 1,
        "orders|5-10": [{
            "id": "@id",
            "from": "@county(true)",
            "to": "@county(true)"
        }]
    }
}

testData.js

module.exports = {
    "ret": true,
    "data|1-10": [{
        "userid": "@id()",
        "username": "@cname()",
        "date": "@date()",
        "avatar": "@image('200x200','red','#fff','avatar')",
        "description": "@paragraph()",
        "ip": "@ip()",
        "email": "@email()"
    }]
}

config.js

// 路由和数据的聚合
module.exports = [{
    method: "get",
    url: '/api/getUserInfo',
    data: require("./api/getUserInfo")
}, {
    method: "post",
    url: '/api/test',
    data: require("./api/testData")
}];

server.js

const express = require("express");
const bodyParser = require("body-parser");
const multipart = require("connect-multiparty");
const Mock = require("mockjs");
const multipartMiddleware = multipart();
const app = express();

// 定义mock方法
const mock = (data, params) => {
    if (Object.prototype.toString.call(data) === "[object Object]") {
        return Mock.mock(data);
    } else if (typeof data === "function") {
        return Mock.mock(data(params));
    } else {
        return "error: data shold be an object or a function.";
    }
};


// 路由和数据的聚合
const config = require("./config")

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// 绑定路由信息
config.forEach(({ method, url, data }) => {
    if (method === "get") {
        app.get(url, (req, res) => {
            res.json(mock(data, req.query));
        });
    } else if (method === "post") {
        app.post(url, multipartMiddleware, (req, res) => {
            res.json(mock(data, req.body));
        });
    } else if (method === "jsonp") {
        app.get(url, (req, res) => {
            const query = req.query;

            const mockData = JSON.stringify(mock(data, req.query));
            const callback =
                "typeof " +
                query.callback +
                ' === "function" && ' +
                query.callback +
                "(" +
                mockData +
                ")";

            res.send(callback);
        });
    }
});

// 支持自定义端口
let port = 8081;
process.argv.forEach((arg, index, arr) => {
    if (arg === "--port") {
        port = arr[index + 1] || 8081;
        return false;
    }
});

module.exports = app.listen(port, () => {
    console.log("Mock Server listening on http://localhost:" + port);
});

index.js

var server = require("./mock/server.js");

四、安装supervisor

最后你会发现我们每一次改变文件都需要执行一遍node index.js ,这样做是真的很麻烦啊,我们可以借助工具,在你本地安装supervisor

$ npm i supervisor -g

使用supervisor执行命令,开启项目,这样你每次更新项目supervisor都会监听到,自动运行项目

supervisor --harmony index

五、github路径:https://github.com/luxueyan1314/mockServer


转载请注明:流年似水 » 前端工程化-搭建本地 Mock 服务

喜欢 (2)or分享 (0)

Warning: copy(https://cn.gravatar.com/avatar/?s=54&d=%2Fwp-content%2Fthemes%2Fyusi1.0%2Fimg%2Fdefault.png&r=g): failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request in /usr/share/nginx/html/timewentby/wp-content/themes/yusi1.0/functions.php on line 239

Warning: copy(/wp-content/themes/yusi1.0/img/default.png): failed to open stream: No such file or directory in /usr/share/nginx/html/timewentby/wp-content/themes/yusi1.0/functions.php on line 243
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址