前端 mock 数据

前端 mock 数据

Easy Mock

由于easy mock线上服务基本打不开的情况,所以有能力的还是做一下本地部署(参考)
在easymock创建一个项目,并将项目的 Base URL 配置到axios的 baseURL,easymock不需要解决跨域的问题。在这里插入图片描述

Yapi

公司内部的话也可以做一下内网部署
用法和easymock差不多,将yapi内项目的mock地址配置到axios的baseURL,也不需要解决跨域的问题

vue cli3 配置本地 mock 数据

通过webpack的 devServer.before 来实现

module.exports = {
  //...
  devServer: {
    before: function(app, server) {
      app.get('/some/path', function(req, res) {
        res.json({ custom: 'response' });
      });
    }
  }
};

如果mock数据过多,我们可以单独建一个文件夹用来存放:
mock/login.js:

const loginMock = [
    {
        type: 'post',
        url: '/api/loginPost',
        res: function (req, res, next) {
            console.log(req.body)
            res.json({ "data": "post" })
        }
    },
    {
        type: 'get',
        url: '/api/loginGet',
        res: function (req, res, next) {
            console.log(req.query)
            res.json({ "data": "get" })
        }
    }
]

module.exports = loginMock

mock/index.js:

module.exports = app => {
    // 使用Express中间件body-parser来解析请求体
    const bodyParser = require('body-parser')
    // 解析 application/json
    app.use(bodyParser.json())
    // 解析 application/x-www-form-urlencoded
    app.use(bodyParser.urlencoded({
        extended: true
    }))
    // 引入mock数据
    const loginMock = require('./login.js')
    const mocks = [
        ...loginMock,
        ...chartMock
    ]

    for (const mock of mocks) {
        app[mock.type](mock.url, mock.res)
    }
}

vue.config.js:

module.exports = {
    ...
    devServer: {
        ...
        // 在服务器内部的所有其他中间件之前执行定制中间件
        before: require('./mock/index.js'),
    }
}

按这样配置完后,基本就完成了本地的数据mock。但有一点不足的就是不能够热更新。每当我们重新修改mock数据,需要重新启动服务才能看到最新的mock数据。
解决这个问题我们可以通过chokidar插件来监控mock文件夹的变化,在发生变化时会清除之前注册的mock-api接口,重新动态挂载新的接口,从而支持热更新。
修改mock/index.js:

const bodyParser = require('body-parser') // 使用Express中间件body-parser来解析请求体
const chokidar = require('chokidar') // 文件夹监控
const path = require('path')

const mockDir = path.join(process.cwd(), 'mock') // 获取文件夹路径

function registerRoutes(app) {
    let mockLastIndex

    const baseMock = require('./base.js')
    const chartMock = require('./chart.js')
    const mocks = [
        ...baseMock,
        ...chartMock
    ]
    for (const mock of mocks) {
        app[mock.type](mock.url, mock.res) // 在express中注册路由
        mockLastIndex = app._router.stack.length // 获取所有已注册路由的长度
    }

    const mockRoutesLength = Object.keys(mocks).length // 获取所有mock数据的长度
    return {
        mockRoutesLength: mockRoutesLength,
        mockStartIndex: mockLastIndex - mockRoutesLength
    }
}
// nodejs清除require缓存 参考:https://blog.hellozwh.com/?post=433
function unregisterRoutes() {
    Object.keys(require.cache).forEach(i => {
        if (i.includes(mockDir)) {
            delete require.cache[require.resolve(i)] // require.resolve 相当于把相对路径转化成绝对路径,避免了自己手写的绝对路径跟cache里的key不一致的问题
        }
    })
}

module.exports = app => {
    // 解析 application/json
    app.use(bodyParser.json())
    // 解析 application/x-www-form-urlencoded
    app.use(bodyParser.urlencoded({
        extended: true
    }))

    const mockRoutes = registerRoutes(app)
    var mockRoutesLength = mockRoutes.mockRoutesLength
    var mockStartIndex = mockRoutes.mockStartIndex

    chokidar.watch(mockDir, { // 监控当前目录
        ignored: /index/, // 忽略index.js文件的变更
        ignoreInitial: true // 忽略对增加文件或者增加文件夹而触发事件
    }).on('all', (event, path) => { // 监听除了ready, raw, and error之外所有的事件类型
        if (event === 'change' || event === 'add') { // 文件内容改变或新增文件时触发
            try {
                // 删除已经挂载到express的路由
                app._router.stack.splice(mockStartIndex, mockRoutesLength)

                // clear routes cache
                unregisterRoutes()

                const mockRoutes = registerRoutes(app)
                mockRoutesLength = mockRoutes.mockRoutesLength
                mockStartIndex = mockRoutes.mockStartIndex

                console.log('请求更新!')
            } catch (error) {
                console.log('请求更新出错:', error)
            }
        }
    })
}

用node启动一个本地服务,来实现mock

在项目根目录建一个mockServer.js文件:

let express = require('express') // 引入express
let Mock = require('mockjs') // 引入mock

let app = express() // 实例化express

app.use(function (req, res, next) {
    res.header('Access-Control-Allow-Origin', '*')
    res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS')
    res.header('Access-Control-Allow-Headers', 'X-Requested-With')
    res.header('Access-Control-Allow-Headers', 'Content-Type')
    next()
})
// mock接口示例
app.post('/api/loginPost', function (req, res) {
    res.json(Mock.mock({
        'status': 200,
        'data|1-9': [{
            'key|+1': 1,
            'mockTitle|1': ['肆无忌惮'],
            'mockContent|1': ['角色精湛主题略荒诞', '理由太短 是让人不安', '疑信参半 却无比期盼', '你的惯犯 圆满', '别让纠缠 显得 孤单'],
            'mockAction|1': ['下载', '试听', '喜欢']
        }]
    }))
})

// 实际项目中肯定有很多mock接口,可以分类目建立,然后引入
const loginMock = require('./mock/login.js')
const chartMock = require('./mock/chart.js')
const mocks = [
    ...loginMock,
    ...chartMock
]
// 挂载这些接口
for (const mock of mocks) {
    app[mock.type](mock.url, mock.res)
}
// 启用一个端口并监听。注意不能和项目一个端口,会把项目停掉
app.listen('3001', () => {
    console.log('监听端口 3001')
})

在vue.config.js里配置跨域代理:

module.exports = {
    ...
    devServer: {
        ...
        // 跨域代理
        proxy: {
            '/web': {
                target: 'http://localhost:3001', // mockServer监听的端口号
                ws: false,
                changeOrigin: true
            }
        }
    }
}

在package.json里配置启动命令:

"scripts": {
    "mock": "node ./mockServer"
},

yarn mock启动mock服务

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值