大家好,我是一条肥鲶鱼。
提示:胆小慎入
前言
对于一个刚入门的前端开发工程师,面对当前3大主流框架是会流口水的。所以前端大佬们已经为我们这些小弟造好了轮子。
今天我们来聊聊目前很火的vue后台管理框架。vue-element-admin
项目地址:https://gitee.com/panjiachen/vue-element-admin.
一、mock.js
1.为什么使用mock.js
我们前端在做开发的时候,后端的接口一直没有出,难道我们要干等着吗?是不是你已经想好怎么摸鱼了。。。。但是mock.js的作者直接打碎了这个美好的想法。
由于 vue-element-admin 是一个纯前端个人项目,所有的数据都是用 mockjs 模拟生成。它的原理是: 拦截了所有的请求并代理到本地,然后进行数据模拟,所以你会发现 network 中没有发出任何的请求。
但它的最大的问题是就是它的实现机制。它会重写浏览器的XMLHttpRequest对象,从而才能拦截所有请求,代理到本地。大部分情况下用起来还是蛮方便的,但就因为它重写了XMLHttpRequest对象,所以比如progress方法,或者一些底层依赖XMLHttpRequest的库都会和它发生不兼容,可以看一下我项目的issues,就知道多少人被坑了。
它还有一个问题是,因为是它本地模拟的数据,实际上不会走任何网络请求。所以本地调试起来很蛋疼,只能通过console.log来调试。就拿vue-element-admin来说,想搞清楚 getInfo()接口返回了什么数据,只能通过看源码或者手动 Debug 才能知道。
2.mock-server.js的出现
在vue-element-admin v4.0版本之后,在本地会启动一个mock-server来模拟数据,线上环境还是继续使用mockjs来进行模拟(因为本项目是一个纯前端项目,你也可以自己搭建一个线上 server 来提供数据)。不管是本地还是线上所有的数据模拟都是基于mockjs生成的,所以只要写一套 mock 数据,就可以在多环境中使用。
该方案的好处是,在保留 mockjs的优势的同时,解决之前的痛点。由于我们的 mock 是完全基于webpack-dev-serve来实现的,所以在你启动前端服务的同时,mock-server就会自动启动,而且这里还通过 chokidar 来观察 mock 文件夹内容的变化。在发生变化时会清除之前注册的mock-api接口,重新动态挂载新的接口,从而支持热更新。有兴趣的可以自己看一下代码mock-server.js。由于是一个真正的server,所以你可以通过控制台中的network,清楚的知道接口返回的数据结构。并且同时解决了之前mockjs会重写 XMLHttpRequest对象,导致很多第三方库失效的问题。
本项目的所有请求都是通过封装的request.js进行发送的,通过阅读源码可以发现所有的请求都设置了一个baseURL,而这个baseURL又是通过读取process.env.VUE_APP_BASE_API这个环境变量来动态设置的,这样方便我们做到不同环境使用不同的 api 地址。
二、使用步骤
1.开发环境
- 因为开发环境用的是mock-server来模拟数据的,所以第一步在vue.config.js中引入mock-server.js。
代码如下(示例):
devServer: {
port: port,
open: true,
overlay: {
warnings: false,
errors: true
},
before: require('./mock/mock-server.js')
},
代码分析:
//before方法:能够在其他所有的中间件之前执行自定义的中间件(意思就是能够拦截axios的请求,返回自定义的请求数据)
下面是书写格式:
before(app) {
app.get('/api/goods', function (req,res) {
res.json({
type:0,
data:goods
})
})
}
代码分析:再看下mock-server.js中的方法是不是发现了什么??
真的是豁然开朗,最后导出的箭头函数刚好与第二张图对应上了,那么内容是否对应上了呢?
上图是我们自定义的api,包括url、type、response。在看到第二张图中初始化api的时候调用responseFake()
函数,是不是也一一对应上了呢!细心的小伙伴可能发现了这行代码app[mock.type](mock.url, mock.response)
,将我们上面的代码拿下来对比一下:app.get('/api/goods', function (res) {})
。发现他们居然长得一模一样!
总结一下: mock-server无非只是封装了app.get()
这种类型的函数。真正实现拦截的是befoce()
方法。
2.生产环境
代码如下(示例):
if (process.env.NODE_ENV === 'production') {
const { mockXHR } = require('../mock')
mockXHR()
}
生产环境是利用纯mock。js来做的,这里就不多介绍,感兴趣的小伙伴可以看看官网链接: http://mockjs.com/.
注意
mock 拦截是基于路由来做的,请确保 mock 数据一定能匹配你的 api 路由,支持正则
// fetchComments 的 mock
{
// url 必须能匹配你的接口路由
// 比如 fetchComments 对应的路由可能是 /article/1/comments 或者 /article/2/comments
// 所以你需要通过正则来进行匹配
url: '/article/[A-Za-z0-9]/comments',
type: 'get', // 必须和你接口定义的类型一样
response: (req, res) => {
// 返回的结果
// req and res detail see
// https://expressjs.com/zh-cn/api.html#req
return {
code: 20000,
data: {
status: 'success'
}
}
}
}
写在最后
大家好,我是一条肥鲶鱼,哈哈哈哈哈哈哈哈哈哈…
本文如果有什么不对的地方,欢迎小伙伴指出哦。