現代開發前後端分離已經變成日常,後端面對後端核心負責業務邏輯,高併發,高流量等需求。前端要各種複雜動效,樣式,以及一大堆此起彼伏的新平臺,新框架,新技術。
一般項目在進行任務派發的時候,前後端的任務是同時下發的,單純的靜態頁面書寫是很快的,這時候就開始等後端接口,等數據了。如果前面接口規範也沒有進行約定,那祝福你!
最無語的時候,就是項目提測的日子,跟後端完成任務差不多,你想你該罵誰吧!經常的情況就是後端寫接口,前端寫頁面,後端寫接口,前端睡覺去了,後端睡覺去了,前端調邏輯,後端睡覺去了,前端邊調樣式變調邏輯調接口,後端調前端提過來的修改,前端睡覺去了,前後重複,中間其實耽誤的大量是時間。
而且一般測試那邊他們一般也不會去看接口看報錯,反正出問題肯定是你前端的,提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('200x100', '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? ) 指定增量
具體使用的時候,翻翻官方文檔,比對著用用就行了,畢竟只是工具。
閱讀更多 Tingno記前端 的文章