mockjs使用心得
在前后端分离的开发过程中,难免会遇到前端等待后台接口数据的场景。之前的做法是临时写一堆测试数据,然后等待后台开发完毕再对接接口,同时删除之前的测试数据。
前段时间跟赛文讨论到这个问题,提到了他们在项目中正在使用mockjs,这是一个专门用于自动生成测试数据的框架,之前略有耳闻,索性也尝试在vue-cli的项目中集成了mockjs,开发体验确实不错。下面是整理的一点心得。
参考:
文档整理
mockjs在前后端分离中,大概的使用流程就是:
- 跟后台约定字段及数据类型,
- 然后通过mockjs相关接口生成模拟数据
- 接口开发完毕,完成对接,移除模拟数据
学习mockjs,可以分成两部分:
- 数据模板语法规则
- 相关
API
由于文档里面已经讲的很详细了,这里就不搬过来了,只是简单记录一下需要注意的地方。
语法
mockjs提供了一套特定的语法用于编写数据模板,指定模拟数据的类型和格式,参考文档。
数据模板中的每个属性由 3 部分构成:属性名、生成规则、属性值: 'name|rule': value
其中,
name值就是我们与后台约定的字段名,value的数据类型和初始值决定了生成规则的具体含义rule生成规则是用来确定字段的生成,这是可选的,共有7种规则min-maxcountmin-max.dmin-dmaxmin-max.dcountcount.dmin-dmaxcount.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。(我对于里面的反向正则匹配很感兴趣,哈哈)
你要请我喝一杯奶茶?
版权声明:自由转载-非商用-保持署名和原文链接。
本站文章均为本人原创,参考文章我都会在文中进行声明,也请您转载时附上署名。
