现代开发前后端分离已经变成日常,后端面对后端核心负责业务逻辑,高并发,高流量等需求。前端要各种复杂动效,样式,以及一大堆此起彼伏的新平台,新框架,新技术。
一般项目在进行任务派发的时候,前后端的任务是同时下发的,单纯的静态页面书写是很快的,这时候就开始等后端接口,等数据了。如果前面接口规范也没有进行约定,那祝福你!
最无语的时候,就是项目提测的日子,跟后端完成任务差不多,你想你该骂谁吧!经常的情况就是后端写接口,前端写页面,后端写接口,前端睡觉去了,后端睡觉去了,前端调逻辑,后端睡觉去了,前端边调样式变调逻辑调接口,后端调前端提过来的修改,前端睡觉去了,前后重复,中间其实耽误的大量是时间。
而且一般测试那边他们一般也不会去看接口看报错,反正出问题肯定是你前端的,提bug也是前端的,领导先上来骂你一段,“你怎么又出问题了!”前端闷着头查找一番,然后找出来最后的锅,领锅人嘿嘿一笑,处理结束。唉,前端这个打杂的,下不了班好像是应该的。
Node.js
Node.js是一个让 JavaScript 运行在服务端的开发平台,它让 JavaScript 成为与PHP、Python、Perl、Ruby 等服务端语言平起平坐的脚本语言。如果您做前端的,使用了现在的三大前端框架,铁定知道。不知道的话,出门右转不送!
Mock.js
Mock.js 是一款模拟数据生成器,旨在帮助前端攻城师独立于后端进行开发,帮助编写单元测试。提供了以下模拟功能:
- 根据数据模板生成模拟数据
- 模拟 Ajax 请求,生成并返回模拟数据
- 基于 HTML 模板生成模拟数据
下面将学习到的nodejs+mockjs搭建的mock服务器安装过程拉出来,共学习。
安装
本文直接说明的是稍稍复杂一点的搭建个mock服务器的版本,需要简单用一下的话,直接引入个包,按照语法上就行了。不过正式联调之后,相关配置要删干净。不然可能会遇到奇怪的bug(我前面就遇到了坑)
1.先安装express服务器
Express 是一个保持最小规模的灵活的 Node.js Web 应用程序开发框架,为 Web 和移动应用程序提供一组强大的功能。
npm install express -g \\安装服务器包 npm install express-generator -g \\安装express的项目快速生成插件 express mockserver \\到指定的文件夹下进行项目文件快速生成,文件名自定义
然后出现如下结果
\\按照里面指示的步骤执行就可以了。 cd mockserver \\切换到项目文件夹 npm install \\安装依赖包 SET DEBUG=mockserver:* & npm start \\启动
然后看到如下界面,express服务器启动正常
2.安装mock包
npm install mockjs \\
打开根目录里面的app.js,在var app = express();下面增加代码,防止下跨域问题
//防止跨域问题 app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"); next(); });
然后按照express默认生成的users模块建立一个新模块,演示新增一个系统模块,在app.js中增加代码
\\var app = express();前面就要引入对应的模块 var systemRouter = require('./routes/system') \\app.use('/users', usersRouter); \\按照users的代码风格加新的 app.use('/system', systemRouter);
routes复制一个users.js,变成system.js开始加代码
var express = require('express'); var router = express.Router(); var Mock = require('mockjs'); \\将mock引入 var Random = Mock.Random; \\生成对应随机对象 /* GET users listing. */ router.get('/warn', function(req, res, next) { var data =Mock.mock({ 'list|20':[{ 'guid':Random.guid(), 'id|+1':1, 'serial_number|1-100':1, 'warn_number|1-100':1, 'warn_name|1':['报警类型1','报警类型2','报警类型3'], 'warn_level|1':['紧急','重要'], 'warn_detail':'环境IP:@ip() ,地址:@county(true) 服务名称:@ctitle() ', 'create_time':Random.datetime(), 'finish_time':Random.datetime(), 'contact':'@cname()', 'description':'@cparagraph', 'img':Random.image(), }] }); res.send({ meta : { message: 'success' }, status:true, data: data.list }) }); module.exports = router;
不过呢,express默认是没有带热更新的,所以,服务器还要重启下。ctrl+c关掉当前进程,npm start重新启动expres
刷新 http://localhost:3000/system/warn页面,打开控制台,就看到了下面的结果
哈哈,是不是跟后端接口给的数据差不多一模一样了!
剩下的其实就是增加不同的接口,给不同的模拟类型了
mock语法
(下面内容都是官方文档上扒的)
最基本的数据模板是 属性名、生成规则、属性值:
'name|rule': value
字段名,加管道参数,输出类型。
- 属性名 和 生成规则 之间用竖线
|
分隔。 - 生成规则 是可选的。
- 生成规则 有 7 种格式:
'name|min-max': value
'name|count': value
'name|min-max.dmin-dmax': value
'name|min-max.dcount': value
'name|count.dmin-dmax': value
'name|count.dcount': value
'name|+step': value
生成规则 的 含义 需要依赖 属性值的类型 才能确定。属性值 中可以含有 @占位符
。属性值 还指定了最终值的初始值和类型。
生成规则和示例:
1. 属性值是字符串 String
'name|min-max': string
通过重复
string
生成一个字符串,重复次数大于等于min
,小于等于max
。'name|count': string
通过重复
string
生成一个字符串,重复次数等于count
。
2. 属性值是数字 Number
'name|+1': number
属性值自动加 1,初始值为
number
。'name|min-max': number
生成一个大于等于
min
、小于等于max
的整数,属性值number
只是用来确定类型。'name|min-max.dmin-dmax': number
生成一个浮点数,整数部分大于等于
min
、小于等于max
,小数部分保留dmin
到dmax
位。
Mock.mock({
'number1|1-100.1-10': 1,
'number2|123.1-10': 1,
'number3|123.3': 1,
'number4|123.10': 1.123
})
// =>
{
"number1": 12.92,
"number2": 123.51,
"number3": 123.777,
"number4": 123.1231091814
}
3. 属性值是布尔型 Boolean
'name|1': boolean
随机生成一个布尔值,值为 true 的概率是 1/2,值为 false 的概率同样是 1/2。
'name|min-max': value
随机生成一个布尔值,值为
value
的概率是min / (min + max)
,值为!value
的概率是max / (min + max)
。
4. 属性值是对象 Object
'name|count': object
从属性值
object
中随机选取count
个属性。'name|min-max': object
从属性值
object
中随机选取min
到max
个属性。
5. 属性值是数组 Array
'name|1': array
从属性值
array
中随机选取 1 个元素,作为最终值。'name|+1': array
从属性值
array
中顺序选取 1 个元素,作为最终值。'name|min-max': array
通过重复属性值
array
生成一个新数组,重复次数大于等于min
,小于等于max
。'name|count': array
通过重复属性值
array
生成一个新数组,重复次数为count
。
6. 属性值是函数 Function
'name': function
执行函数
function
,取其返回值作为最终的属性值,函数的上下文为属性'name'
所在的对象。
7. 属性值是正则表达式 RegExp
'name': regexp
根据正则表达式
regexp
反向生成可以匹配它的字符串。用于生成自定义格式的字符串。Mock.mock({ 'regexp1': /[a-z][A-Z][0-9]/, 'regexp2': /\w\W\s\S\d\D/, 'regexp3': /\d{5,10}/ }) // => { "regexp1": "pJ7", "regexp2": "F)\fp1G", "regexp3": "561659409" }
数据占位符定义规范 DPD
占位符 只是在属性值字符串中占个位置,并不出现在最终的属性值中。
占位符 的格式为:
@占位符
@占位符(参数 [, 参数])
注意:
- 用
@
来标识其后的字符串是 占位符。 - 占位符 引用的是
Mock.Random
中的方法。 - 通过
Mock.Random.extend()
来扩展自定义占位符。 - 占位符 也可以引用 数据模板 中的属性。
- 占位符 会优先引用 数据模板 中的属性。
- 占位符 支持 相对路径 和 绝对路径。
Mock.mock({
name: {
first: '@FIRST',
middle: '@FIRST',
last: '@LAST',
full: '@first @middle @last'
}
})
// =>
{
"name": {
"first": "Charles",
"middle": "Brenda",
"last": "Lopez",
"full": "Charles Brenda Lopez"
}
}
具体的数据占位符可以模拟什么数据呢?先看看下面列举的,避免重复造轮子不是!
- Random.boolean( min?, max?, current? ) 布尔值
- Random.natural( min?, max? ) 自然数(都是正整数和0)
- Random.integer( min?, max? ) 整数(包含正负整数和0)
- Random.float( min?, max?, dmin?, dmax? ) 浮点数,随机大小和小数点后位数
- Random.character( pool? ) 随机字符包含大小写和字符
- Random.string( pool?, min?, max? ) 随机字符串,可指定字符和长度
- Random.range(start?, stop, step?) 指定数组范围例如 [1,2,3,4,5]
- Random.date( format? ) 随机日期
- Random.time( format? ) 随机时间
- Random.datetime( format? ) 随机日期和时间
- Random.now( unit?, format? ) 当前时间,不能算随机,算格式化当前时间
- Random.image( size?, background?, foreground?, format?, text? ) 随机图片,生成指定url的地址带上参数。希望这个在本地实现。
- Random.dataImage(‘200×100’, ‘Hello Mock.js!’) 生成一个base64位的图片文件
- Random.color() 随机hex颜色值
- Random.hex() 同上
- Random.rgb() 随机rgb颜色
- Random.rgba() 带透明度的颜色值
- Random.hsl() hsl格式的颜色值
- Random.paragraph( min?, max? ) 随机英文段落,很乱。
- Random.sentence( min?, max? ) 随机英文句子,依然很乱
- Random.word( min?, max? ) 随机英文单词
- Random.title( min?, max? ) 随机英文标题
- Random.cparagraph( min?, max? ) 随机中文段落,很乱
- Random.csentence( min?, max? ) 随机中文句子
- Random.cword( pool?, min?, max? ) 随机中文单词
- Random.ctitle( min?, max? ) 随机中文标题,跟单词效果一样感觉
- Random.first() 随机英文姓名的前面
- Random.last() 随机英文姓名的后面
- Random.name( middle? ) 随机姓名,按照名在前,姓在后说明。
- Random.cfirst() 随机中文姓名的姓
- Random.clast() 随机中文姓名的名
- Random.cname( middle? ) 随机姓名,按照姓在前,名在后说明。
- Random.url() 随机url地址
- Random.domain() 随机主机名
- Random.protocol() 随机协议名
- Random.tld() 随机tld顶级域名
- Random.email() 随机email地址
- Random.ip() 随机ip地址
- Random.region() 随机地址区域指的是[‘东北’, ‘华北’, ‘华东’, ‘华中’, ‘华南’, ‘西南’, ‘西北’]
- Random.province() 随机省份
- Random.city( prefix? ) 随机城市
- Random.county( prefix? ) 随机县
- Random.zip() 随机邮政编码
- Random.capitalize( word ) 格式化,首字母大写
- Random.upper( str ) 格式化,大写文本
- Random.lower( str ) 格式化,小写文本
- Random.pick( arr ) 随机挑选一个值
- Random.shuffle( arr ) 拖拽乱序一个数组排列
- Random.guid() 随机一个guid值
- Random.id() 随机id值
- Random.increment( step? ) 指定增量
具体使用的时候,翻翻官方文档,比对着用用就行了,毕竟只是工具。