前端開發,需要和后台聯調;很多時候,前端開發並不需要等后台完全寫好接口在去聯調,自己可以寫死數據,渲染數據,加樣式。后台人員有時會很忙,他沒有時間寫好返回所有的數據等等,特別是新開一個項目,從零開始的那種,前端要是等后台寫好,開發效率就不高了。所以自己造數據很重要。有一段時間,我每天早上來就催后台給我開服務器,應該不開的話,代碼不好寫,效率不快,會影響每天的任務的,影響了的話就要苦逼的加班。
我做過一個項目,進件新增編輯的,表單字段,一個表單頁面有20~30來個字段,填寫完最快都要半首歌的時間,頁面刷新又得重新填,又得花那個時間。后來同事小強建議寫死一個json
數據自動填寫,填都不用填了。其實省下不少時間。突然間我就意識到寫假數據對於一個前端來說,挺重要,可以節省時間,多出來的時間,可以休息,測試項目的功能或者學習新東西。
在上一家體育公司中,我寫了一個體測數據的頁面,一個頁面很長,密密麻麻的全是體測的數據。記得當時頁面的每一部分的數據,我都是用同一個數據,其實這樣子不好,因為頁面需要的最終數據(比如文字的長度,是否符合該字段正則表達式等等)和寫的假數據有時很大出入,會影響頁面效果的。如果有問題,你就要重新寫樣式,加班加點。之前寫過一個大屏直播的頁面,用戶的那個名稱,一般人都是2到3個漢字,所以我自然沒有考慮到4個漢字的名稱,結果悲劇了,真有4個字的人名,然后那一塊樣式排版亂掉,我又得改。這種場景就需要一個js
工具幫我隨機生成2到4字的名字。
上圖為2019年的工作環境
研究了一個專門造假數據的庫,叫mock
。其實這個東西我在2018年的年初就已經知道了,有一次面試,面試官問過這個問題(結果是流淚的),后來只不過看了2天的官方文檔,就讓它在一邊吃灰,因為在上一家體育公司的項目中應用場景不多。最近項目閑下來,我花了1天的時間(其實就是半天)寫了一個工具類js,方便自己以后在新開項目時或者特別需要假數據時使用。
mock
有兩個好處:1. 隨機的生成假數據,每次頁面刷新都不一樣;2. 它可以攔截ajax
請求,就是說當你定義在mock
里面的接口路徑和真實的后台接口路徑一樣時,前者就把后者攔截。
代碼如下面所示哈:
import Mock from 'mockjs';
let Random = Mock.Random;
//枚舉的工具對象
//其實就是`map`方法遍歷一個數組,生成一個數組和一個`code`數組,`code`和新數組的序號是一致的,所以就可以輕易的輸入`code`拿到想要的值
class EsEnum {
constructor(arr) {
let typeArr = [];
if (!Array.isArray(arr)){
throw 'arr is not an array!';
return;
}
arr.map(element => {
if(!element.code || !element.name) {
return;
}
// 保存code值組成的數組,方便A.getName(name)類型的調用
typeArr.push(element.code);
// 根據code生成不同屬性值,以便A.B.name類型的調用
this[element.code] = element;
});
// 保存源數組
this.arr = arr;
this.typeArr = typeArr;
}
// 根據code得到對象
valueOf(code) {
return this.arr[this.typeArr.indexOf(code)];
}
// 根據code獲取name值
getNameByCode(code){
let prop = this.valueOf(code);
if (!prop){
throw 'No enum constant' + code;
return;
}
return prop.name;
}
// 返回源數組
getValues() {
return this.arr;
}
}
// 配置攔截 ajax 的請求時的行為,支持的配置項目有 timeout。
Mock.setup({
timeout: '200 - 400'
})
//接口api
/**
* * @description: 通用工具類
* * @author: StephenWu5
* * @paras 接口鏈接,接口類型,返回數據結構,返回數據的長度
* * @date: 2019-12-3 15:38:27
*/
export const createApiByMock = function(apiUrl,apiType,paraSet) {
let data = []; //等下要返回的數據
let returnData ={};
let dataLength = paraSet.dataLength || 10;
for (let i = 0; i < dataLength; i++) {
let images = [1,2,3].map(x=>Random.image('200x100', Random.color(), Random.word(2,6))); //隨機成長3個圖片信息 尺寸 顏色 和隨機字母的數組
let paraSetNew = JSON.parse(JSON.stringify(paraSet))
let dataTypeEnum = new EsEnum([
//==============================================配置的開始==========================================================
{code: '0', i}, //id 唯一性
{code: '1', name: Random.cname()}, //中文姓名 cfirst 模擬姓氏 clast 模擬名字 name 英文名字
{code: '2', name: Random.cword(8,20)}, //標題 8和20是長度
{code: '3', name: Random.integer(100,5000)}, // 100到5000的隨機整數 natural 返回隨機的自然數
{code: '4', name: images.slice(0,Random.integer(1,3))},//截取隨機一到三個圖片
{code: '5', name: Random.image('200x100', '#4A7BF7', 'picture')}, //模擬圖片 寬高不指定則隨機
{code: '6', name: Random.date()}, //日期 yyyy-MM-dd yyyy-mm-dd是指定格式
{code: '7', name: Random.time()}, //時間
{code: '8', name: Random.province()}, //省
{code: '9', name: Random.city()}, //市 Mock.mock('@city(true)') 加參數true會有奇效哈
{code: '10', name: Random.county()}, //區 Mock.mock('@county(true)')
{code: '11', name: Mock.mock('@EMAIL()')}, //郵箱
{code: '12', name: Mock.mock(/^1[0-9]{10}$/)}, //手機(座機) 這里可以正則
{code: '13', name: Mock.mock('13531544954')}, //身份證
Mock.mock({ code: '14', "name|1":['精品語文班','精品作業A班','英語班','語文班']}), //身份證包括一切的枚舉,使用率最高
{code: '21', name: Random.csentence(5, 10)}, //生成一條隨機的中文句子
{code: '22', name: Random.cparagraph(0, 10)}, //隨機生成0到10段句子
{code: '23', name: Random.url()}, //url
{code: '24', name: Random.ip()}, //ip
//==============================================配置的結束==========================================================
])
for(let key in paraSetNew){
if(!key){
return;
}
if(key === 'dataLength'){
continue;
}
paraSetNew[''+key] = dataTypeEnum[""+paraSet[""+key]]['name']
}
delete paraSetNew.dataLength; //就看你想不想留dataLength;
data.push(
//{allData: (dataTypeEnum)}, //這里就是精華所在哈
paraSetNew
)
}
//利用assign添加默認值 status message
returnData = Object.assign({
status: 200,
message: 'success',
length: data.length,
}, {data});
// Mock.mock( url, post/get , 返回的數據);
Mock.mock(apiUrl,apiType, returnData); // 獲取驗證碼
}
使用就是新建一個js
文件,把它導入到項目中,使用如下:
這一步只是在項目注冊這個api
,還要寫一個調用該api
的方法才可以。真有一個下午,就是今天,我在項目中引入這個工具類,也注冊了,看不到效果,我以為是這兩個地方寫錯了,找來找去,原來是缺了調用該api的方法(就是最后一步下方的代碼)。半小時就這樣折騰沒了。西湖啊,我的淚。
import {createApiByMock} from './mock';
//使用實例 dataLength 是返回數組的長度哈
let paraSet = {
name: 1,
age: 3,
dataLength: 10
}
createApiByMock('http://localhost:8080/getMockData','get',paraSet);
最后一步,調用該api
。
其實這個代碼和mock無關,只不過我的接口名和項目的不一樣,所以就寫成這樣子。
//得到mock數據,
export const getMockData = (data) => Request.get(`/getMockData`, data, createHeader());
這樣子就可以快速拿到自己想要的數據,簡單。需要特別注意的是,和mock
相關的代碼,特別是第2部分的代碼,生產,測試環境不能提交,要是不小心提交了,領導會很生氣的,他會讓你不能下班或者不上班,所以還需要在項目中加上環境判斷的代碼,決定是否使用注冊api
那部分的代碼哈。
寫到這里,我突然感覺,那些vue
,jquery
,react
其實就是和我這個js
是類似的啊,只不過前者就是很多技術大佬寫出來,維護,功能強大,可以做很多事情,文件體積大,經過了單元測試,使用的話不會出什么問題;而我這個體積小,功能單一,只能做一件事情,比較辣雞。前者是優秀電視劇《甄嬛傳》的話,后者就是抖音短視頻。前者后者只不過都是前端工程師開發的工具,讓我們快速的寫頁面,和那些ppt模版,編輯器vscode
,vim
沒有什么兩樣都屬於工具來的,類似父親的泥水刀,農民耕田用的水牛,廚師的菜刀。
以后有空閑的話,再搞axios
,utils
,vue組件echart
等幾個常用的工具類出來吧。方便你我她他它使用,順便假裝大佬哈哈哈哈哈哈哈。
最后,歡迎關注我的公眾號。