出現的原因
1、開發進度的不同
2、前后端分離
優勢
1、前后端分離—–定義好接口文檔之后,前端人員不用再等待后臺的接口
2、增加測試的真實性
3、可攔截Ajax請求,并返回請求
4、易上手
5、數據類型豐富、支持擴展
安裝及使用
- 引入mockjs : http://mockjs.com/dist/mock.js
- 模擬數據
Mock.mock( rurl, rtype, function( options ) )
記錄用于生成響應數據的函數。當攔截到匹配 rurl 和 rtype 的 Ajax 請求時,函數 function(options) 將被執行,并把執行結果作為響應數據返回。
rurl: 請求的路徑
rtype: 請求的方式 GET POST 等
function(options): 表示用于生成響應數據的函數
options
指向本次請求的 Ajax 選項集,含有 url、type 和 body 三個屬性
// 第一種
// 第一個參數是接口
// 第二個參數是返回的對象 ,返回一個json對象
// 在實際前后端分離開發的時候,可以攔截ajax請求
Mock.mock('http://aaa.com', {
// 屬性名|生成規則: 屬性值
'name|3': 'fei',
'age|20-30': 25,
});
// 第二種
// 可提取請求的參數與信息
Mock.mock('http://test.com', function(options) {
console.log(options);
return Mock.mock({
"user|1-3": [{
'name': '@cname',
'id|+1': 88
}
]
});
});
// 第三種
// 可提取請求的參數與信息,并且區別不同的請求方式,如果出現相同的接口,但請求方式的不同就可以使用以下的方式了
// 接口一一對應
// 請求方式
// 回調函數:攔截到請求所做的一些操作,要有返回值,其實就是響應,這樣我們就可以在實際開發做一些 其他操作:監聽 get put delete post, 并對數據總增刪改查的操作
Mock.mock('http://test.com', 'post', function(options) {
console.log(options);
return Mock.mock({
"user|1-3": [{
'name': '@cname',
'id|+1': 88
}
]
});
});
// 第四種
// 模擬數據
// 適用場景: 可以保存數據,配合其他接口實現接口攔截對其增刪改查
let user = Mock.mock({
'data|10': [
{
'name': '@cname',
'age|10-20': 0,
'address': '@city(true)',
'id': '@id'
}
]
});
- ajax請求數據
// 模擬ajax請求,mock則攔截相同的url
ajax({
url: 'http://aaa.com',
method: 'POST',
data: {
name: 'hyj',
age: 18
},
callback: function (data) {
console.log(data);
}
});
4.mock基本數據
對于一些常用的自動隨機生成的數據,MOCK提供了一些方法,然后可以在實際開發當中選取一些適用的隨機函數,模擬類似的數據,
適用場景:用戶名 用戶的地址 用戶的id 用戶的年齡等
基本模板:屬性名|生成規則: 屬性值
- 數組
'user|1-3': [], // 隨機生成1到3個數組元素
- 姓名
'name': '@cname', // 隨機中文名稱
- ID
'id|+1': 1, // 屬性值自動加 1,初始值為1
- 年齡
'age|18-28': 0, // 18至28以內隨機整數, 0只是用來確定類型
- 時間
'time': '@date("yyyy-MM-dd")', // 日期
- 城市
'city': '@city(true)', // 中國城市
- 顏色
'color': '@color', // 16進制顏色
- 布爾
'isMale|1': true, // 布爾值
'isFat|1-2': true, // true的概率是1/3
- 從某對象中抽取屬性
var params = {a: 1, b: 2, c: 3};
'params|2': params, // 從params對象中隨機獲取2個屬性
'params2|1-3': params, // 從params對象中隨機獲取1至3個屬性
- 數組抽取
'arr|1': ['a', 'b'], // 隨機選取 1 個元素
'arr1|+1': ['c', 'b', 'a'], // array中順序選取元素作為結果
'arr2|2': ['b', 'a'] // 重復2次元素生成一個新數組
'email': '@email'
- 設置響應時間
適用場景:模擬請求耗時,可做等待優化,例如:在加載數據的時候,顯示加載GIF圖
// 設置4秒后再響應
Mock.setup({ timeout: 1000 });
// 設置1秒至3秒間響應
Mock.setup({ timeout: '1000-3000' });
小案例:
index.js
window.addEventListener('DOMContentLoaded', domLoad);
function domLoad() {
var globalData = null;
var tempData = null;
ajax({
url: 'http://127.0.0.1:3000/api/data',
callback(data) {
console.log(data);
globalData = JSON.parse(data).data
// 初次渲染 數據 容器 回調函數
render(globalData, container, addEvent);
}
});
console.log(globalData); // null
function render(data, parent, callback) {
var html = '';
for (var i = 0; i < data.length; i++) {
html += `
<ul>
<li>${data[i].id}</li>
<li>${data[i].name}</li>
<li>${data[i].age}</li>
<li>${data[i].address}</li>
<li><button data-index="${i}" class="update">修改</button><button data-id="${data[i].id}" class="del">刪除</button></li>
</ul>`
}
parent.innerHTML = html;
callback && callback();
}
function addEvent() {
// 獲取修改按鈕
var updateBtn = document.getElementsByClassName('update');
// 獲取刪除按鈕
var delBtn = document.getElementsByClassName('del');
// 姓名輸入框 年齡輸入框 地址輸入框
var nameIpt = document.getElementById('name');
var ageIpt = document.getElementById('age');
var addressIpt = document.getElementById('address');
// 提交功能按鈕
var submit = document.getElementById('submit');
// 循環的綁定修改按鈕,和刪除按鈕
for (let i = 0; i < delBtn.length; i++) {
updateBtn[i].onclick = function () {
tempData = globalData[i];
// 將臨時的用戶信息給了input框
nameIpt.value = tempData.name;
ageIpt.value = tempData.age;
addressIpt.value = tempData.address;
}
delBtn[i].onclick = function () {
// 請求刪除相對應id的用戶
ajax({
url: 'http://127.0.0.1:3000/api/delete',
method: 'POST',
data:{
id: delBtn[i].dataset.id
},
callback(data) {
// 重新渲染數據
render(JSON.parse(data), container, addEvent);
}
})
}
}
// 提交修改信息
submit.onclick = function () {
// 獲取所修改后的信息
tempData.name = nameIpt.value;
tempData.age = ageIpt.value;
tempData.address = addressIpt.value;
// 更新的接口
ajax({
url: 'http://127.0.0.1:3000/api/update',
method: 'POST',
data:tempData,
callback(data) {
// 從新渲染頁面
render(JSON.parse(data), container, addEvent);
}
});
}
}
}
mockApi.js
// 存儲數據
let user = Mock.mock({
'data|10': [
{
'name': '@cname', // 隨機名字
'age|10-20': 0,
'address': '@city()',
'id': '@id'
}
]
});
// 攔截請求數據的接口
Mock.mock('http://127.0.0.1:3000/api/data?', user);
// 修改數據接口
Mock.mock('http://127.0.0.1:3000/api/update', 'post', update);
// 刪除數據的接口
Mock.mock('http://127.0.0.1:3000/api/delete', 'post', deleteFn);
function update(opt) {
// opt:請求的信息
console.log(opt);
var userData = JSON.parse(opt.body);
// 比對修改對應的用戶
for (var i = 0; i < user.data.length; i++) {
if (user.data[i].id === userData.id) {
user.data[i] = userData;
}
}
return user.data;
}
function deleteFn(opt) {
let id = JSON.parse(opt.body).id;
// 比對id,刪除對應的用戶
for (var i = 0; i < user.data.length; i++) {
if (user.data[i].id === id) {
user.data.splice(i, 1);
break;
}
}
return user.data
}