mockjs使用心得
在前后端分离的开发过程中,难免会遇到前端等待后台接口数据的场景。之前的做法是临时写一堆测试数据,然后等待后台开发完毕再对接接口,同时删除之前的测试数据。
前段时间跟赛文讨论到这个问题,提到了他们在项目中正在使用mockjs
,这是一个专门用于自动生成测试数据的框架,之前略有耳闻,索性也尝试在vue-cli
的项目中集成了mockjs
,开发体验确实不错。下面是整理的一点心得。
参考:
文档整理
mockjs在前后端分离中,大概的使用流程就是:
- 跟后台约定字段及数据类型,
- 然后通过mockjs相关接口生成模拟数据
- 接口开发完毕,完成对接,移除模拟数据
学习mockjs
,可以分成两部分:
- 数据模板语法规则
- 相关
API
由于文档里面已经讲的很详细了,这里就不搬过来了,只是简单记录一下需要注意的地方。
语法
mockjs
提供了一套特定的语法用于编写数据模板,指定模拟数据的类型和格式,参考文档。
数据模板中的每个属性由 3 部分构成:属性名、生成规则、属性值: 'name|rule': value
其中,
name
值就是我们与后台约定的字段名,value
的数据类型和初始值决定了生成规则的具体含义rule
生成规则是用来确定字段的生成,这是可选的,共有7种规则min-max
count
min-max.dmin-dmax
min-max.dcount
count.dmin-dmax
count.dcount
,+step
,
这里的介绍有点模糊,value
的类型必定在JavaScript的7种类型String
,Number
,Boolean
,Object
,Array
,Function
,RegExp
中的某一种,value
的类型不同,对应的生成规则也不同,举个例子
{
'id|1-3':10,
'name|1-3':'abc',
}
这里的规则1-3
对应min-max
第一个id|1-3
表示生成id
字段,其而对应的value
值10
是Number
,只是用来帮助规则确定实际的含义,这里是:id
值位于1~3
的范围内。 第二个name|1-3
表示生成name
字段,其value
值类型为String
,表示生成的数据由该字符串重复1~3
次而成的。
理解“规则的含义由对应的值确定”这一点之后,mockjs
的语法规则基本上就掌握了。至于各个数据类型对应的各个规则的含义,多多练习即可。
语法部分需要注意的就是当value
值为RegExp
类型时,甚至可以根据该正则表达式,反向生成可以匹配它的字符串。这是一个非常强大的功能,这样我们可以用来生成自定义格式的字符串
mock
通过Mock.mock
方法可以快速模拟数据,参考文档
var Mock = require("mockjs");
var data = Mock.mock({
'list|1-10': [{
'id|+1':1
}],
});
mock
方法有多个重载,我用的最多的就是拦截指定url的ajax请求,
Mock.mock( rurl?, rtype?, template|function( options ) )
参数含义为:
rurl
,表示需要拦截的 URL,可以是 URL 字符串或 URL 正则rtype
,表示需要拦截的 Ajax 请求类型。例如 GET、POST、PUT、DELETE 等template
,表示数据模板,可以是对象或字符串,由前面的语法规则组成function(options)
,表示用于生成响应数据的函数。options
,本次请求的 Ajax 选项集
其实现原理是:
从 1.0 开始,Mock.js 通过覆盖和模拟原生 XMLHttpRequest 的行为来拦截 Ajax 请求
Random
Mock.Random 是一个工具类,用于生成各种随机数据。
这个函数包含了一系列指令函数,用于生成常见的字段,比如image
,color
,text
等,
var Random = Mock.Random
console.log(Random.email());
在数据模板中,可以通过占位符的形式,生成对应的模拟数据,非常方便。此外针对文本,还有专门的中文指令(是不是很人性化)。
{
'user_email': '@email'
}
可以把Random
工具类理解为内置的数据模板语法糖,我们可以快速生成模拟数据,而不必编写具体的数据模板。
其他
上面的mock
和Random
是比较常用方法,此外还有其他几个API
Mock.setup( settings )
,用于配置拦截 Ajax 请求时的行为。目前支持的配置项只有:timeoutMock.valid( template, data )
,校验真实数据 data 是否与数据模板 template 匹配,可以用于单元测试Mock.toJSONSchema( template )
,把 Mock.js 风格的数据模板 template 转换成 JSON Schema,这个我暂时还没有研究过
在开发环境中集成
直接前端引入
我的vue-cli
项目的src
目录层次大概如下所示
|- api 请求接口
|- _axios.js 请求配置及相关拦截器
|- _mock.js 模拟对应请求url的返回数据
|- test.js 业务接口文件
|- ...
|- assets 静态资源
|- components 公共组件
|- filters 全局过滤器,
|- pages 页面模块
|- p_1
|- p_2
|- ...
|- router 页面路由配置
|- store vuex状态管理
|- test 测试文件
|- App.vue
|- main.js 入口文件
mockjs
可以拦截对应的ajax请求,然后返回对应的数据,比如test.js
文件中包含如下接口
// test.js
import axios from "axios"
export const test = (params)=>{
return axios.post(`/api/test`, params).then(res=>res.data);
};
我们只需要在_mock.js
中拦截这个请求的路径api/test
,根据跟后台预先预定的字段,生成模拟数据
// mock.js
import Mock from "mockjs"
// 拦截对应的url
Mock.mock(/\/api\/test/, 'get', {
'list|10': [{
'id|+1': 1,
'comment_id': 0,
'uid': '@id',
'created_time': '@datetime',
'content': '@csentence',
}],
'total': 56
});
同时记得在入口文件main.js
引入
// main.js
import "@/api/_mock"
import "@/api/_axios"
可以看见,我们可以在_mock.js
中拦截任何我们需要的接口,然后生成一大堆测试数据,在对接接口时,只需要删除对应的请求拦截即可。
如果模拟接口数量较多,我们可以考虑将其拆分成多个文件然后按需引入。不过当后台接口开发完毕时,之前的拦截请求也没有必要了。
上面只是简单地通过将_mock.js
是否引入main.js
来区分开发环境和接口对接正式环境,这对于开发者来说并不是很友好,需要手动修改引入文件,还需要手动删除多余的mock
拦截。
一种更好的选择应当是使用类似于vue-cli
的npm run dev
和npm run build
这样的指令来切换开发环境。
dev server api
在vue-cli
的目录/build/dev-server.js
中我们可以发现,开发环境的服务器是使用express
搭建的。
因此我们可以直接设置对应的路由请求并返回模拟数据,这样我们就不需要手动地在main.js
中引入和移除_mock.js
文件。
// express模拟请求
app.get('/api/data', (req, res)=>{
res.send(Mock.mock({
"list|5": [{
"id|+1":1,
"name": "@word"
}]
}));
})
这里带来的问题是如果模拟接口过多,在dev-server
中会包含过多的模拟数据代码,这肯定不是一个明智之举。此外,由于直接调用了Mock.mock(template)
的形式,并没有用到其拦截url请求的特性。(如果后台是nodejs的话,可以让后台先使用mockjs直接返回模拟数据,这样就不需要前端处理了~)
我们可以通过express的路由组件,将对应的模拟请求置于单独的文件中(跟前面纯前端处理类似),整个世界就清静了。
新建一个mock
文件夹,放置所有的模拟请求
// mock/index.js
var express = require("express");
var router = express.Router();
var Mock = require("mockjs");
router.use("/data", function(req, res, next) {
res.send(Mock.mock({
"list|5": [{
"id|+1": 1,
"name": "@word",
"title": "@ctitle"
}]
}));
});
module.exports = router;
在dev-server
中,使用该路由组件即可
if(config.dev.isMock){
app.use('/api', require('../mock/'))
}
上面的config.dev.isMock
是在配置文件/config/index.js
中额外增加的配置变量,来决定是否使用模拟路由组件,从而在正式接口和模拟接口之间来回切换
最后
上面简单整理了mockjs的使用,以及集成到vue-cli的方法。
当然,mockjs不仅限于vue-cli的使用中,在其他很多需要模拟数据的地方 ,都可以使用mockjs。(我对于里面的反向正则匹配很感兴趣,哈哈)
你要请我喝一杯奶茶?
版权声明:自由转载-非商用-保持署名和原文链接。
本站文章均为本人原创,参考文章我都会在文中进行声明,也请您转载时附上署名。