數據mock 1. 前期定義數據結構(后期不能改) 2. 前期確定傳參方式 resufApi (后期不能改) 簡潔: 會用,會改 1. mock目錄拷貝到項目下 2. 修改package.json + scripts 的 key "mock": "nodemon ./mock/server.js" 3. yarn add json-server --save 安裝依賴 4. yarn add mockjs --save 安裝依賴 4.5 添加代理項 app.use( proxy("/mock", { target: 'http://localhost:3333', changeOrigin: true }) ); 5. yarn mock 啟動mock服務器 6. yarn start 啟動react開發服務器 組件內部發送請求: /mock/接口名 配置自己的數據接口: ./mock/db.js 'banner|2': [ { // 屬性 id 是一個自增數,起始值為 1,每次增 1 'id|+1': 1, title: "@ctitle(4,8)",//標題型中文4到8個字 sub_title: "@ctitle(6,12)", banner: mr.image('750x501', mr.color(), mr.cword(4,10)),//banner不變 time: "@integer(1553425967486,1553475967486)", detail:{ icon:mr.image('20x20', mr.color(), mr.cword(1,2)),//20X20尺寸 auth:"@cname()",//百家姓 content:"@cparagraph(10,40)"//正文 } } ]
mock文件夾配置
npm i mockjs --save
npm json-erver --save
最后跑起來是npm run server
在pack.json 內更改
在mock內的db文件內
// 用mockjs模擬生成數據
var Mock = require('mockjs');
let mr = Mock.Random;//提取mock的隨機對象
//隨機id和圖片
let mapData = (n) => {
var data = [];
for (var i = 1; i <= n; i++) {
data.push({
id: i,
title: "@ctitle(8,12)",
des: "@csentence(10, 20)",
time: "@integer(1553425967486,1553475967486)",
detail:{
auth:"@cname()",
content:"@cparagraph(10,40)",
auth_icon:mr.image('50x50', mr.color(), mr.cword(1))
}
})
}
return data
};
//json-server 要對象||函數(返回mock后的數據)
module.exports = {
...Mock.mock({
'home': mapData(32),//解決 auth_icon 不隨機
'follow': mapData(21),
'column': mapData(11),
'banner|2': [
{
// 屬性 id 是一個自增數,起始值為 1,每次增 1
'id|+1': 1,
title: "@ctitle(4,8)",//標題型中文4到8個字
sub_title: "@ctitle(6,12)",
banner: mr.image('750x501', mr.color(), mr.cword(4,10)),//banner不變
time: "@integer(1553425967486,1553475967486)",
detail:{
icon:mr.image('20x20', mr.color(), mr.cword(1,2)),//20X20尺寸
auth:"@cname()",//百家姓
content:"@cparagraph(10,40)"//正文
}
}
]
})
};
在server.js文件內
const jsonServer = require('json-server');//在node里面使用json-server包
const db = require('./db.js');//引入mockjs配置模塊
var Mock = require('mockjs');
let mr = Mock.Random;//提取mock的隨機對象
const server = jsonServer.create();//創建jsonserver 服務對象
const router = jsonServer.router(db);//創建路由對象
const middlewares = jsonServer.defaults();
let mock='/mock';//創建根api名 這里的 /mock 如同 后端真實/api
//路由自定義
const rewriter = jsonServer.rewriter({
[mock+"/*"]: "/$1",
"/product\\?dataName=:dataName": "/:dataName",
"/banner\\?dataName=:dataName": "/:dataName",
"/detail\\?dataName=:dataName&id=:id": "/:dataName/:id",
// "/product/del\\?dataName=:dataName&id=:id": "/:dataName/:id",
// "/product/add\\?dataName=:dataName": "/:dataName",
// "/product/check\\?dataName=:dataName&id=:id": "/:dataName/:id"
});
server.use(middlewares);
server.use((request, res, next) => {//可選 統一修改請求方式
// console.log(1)
// request.method = 'GET';
next();
});
server.use(jsonServer.bodyParser);//抓取body數據使用json-server中間件
//模擬校驗
server.use(mock+'/login', (req, res) => {
console.log(req.query, req.body);//抓取提交過來的query和body
let username=req.query.username;
let password=req.query.password;
(username === 'aa' && password === 'aa123')?
res.jsonp({
"error": 0,
"msg": "登錄成功",
"page_data": {
"follow": mr.integer(1,5),
"fans": mr.integer(1,5),
"nikename": mr.cname(),
"icon": mr.image('20x20',mr.color(),mr.cword(1)),
"time": mr.integer(13,13)
}
}) :
res.jsonp({
"error": 1,
"msg": "登錄失敗",
})
});
server.use(mock+'/reg', (req, res) => {
let username=req.query.username;
(username !== 'aa') ?
res.jsonp({
"error": 0,
"msg": "注冊成功",
"page_data": {
"follow": mr.integer(0,0),
"fans": mr.integer(0,0),
"nikename": mr.cname(),
"icon": mr.image('20x20',mr.color(),mr.cword(1)),
"time": mr.integer(13,13)
}
}) :
res.jsonp({
"error": 1,
"msg": "注冊失敗",
})
});
server.use(rewriter);//路由重寫
server.use(router);//路由響應
//自定義返回內容
router.render = (req, res) => {
let len = Object.keys(res.locals.data).length; //判斷數據是不是空數組和空對象
// console.log(len);
setTimeout(()=>{
res.jsonp({
error: len !== 0 ? 0 : 1,
msg: len !== 0 ? '成功' : '失敗',
page_data: res.locals.data
})
},1000)
// res.jsonp(res.locals.data)
};
//開啟jsonserver服務
server.listen(3333, () => {
console.log('mock server is running')
});
最后再把react跑起來 npm start
import React from 'react'
import ReactDom from 'react-dom'
class App extends React.Component{
state={
msg:'-',
};
render(){
return (
<div className="app">
<h3>mock</h3>
<input type="button" value="讀接口_地址欄傳參" onClick={this.getMock}/>
<input type="button" value="讀接口_非地址欄傳參" onClick={this.postMock}/>
<input type="file" ref="f1" />
<input type="button" value="讀接口_上傳文件" onClick={this.postMockFile}/>
</div>
)
}
getMock = () => {
fetch(
`/mock/home?_page=2&_limit=2`
).then(
res => res.json()
).then(
data => console.log(data)
)
};
postMock = () => {
let params = new URLSearchParams();
params.append("username","alex");
params.append("password","alex123");
let headers = new Headers();
headers.append("Content-type","application/x-www-form-urlencoded");
fetch(
`/mock/login`,
{
method:'POST', //默認get
// headers:{"Content-type":"application/x-www-form-urlencoded"},
headers:headers,
// body:params//{username:'alex',password:'alex123'}//URLSearchPrams
body:"username=alex&password=alex123"
}
).then(
res => res.json()
).then(
data => console.log(data)
)
};
postMockFile = () => {
let formData = new FormData();
formData.append("username", "heheda");
formData.append("password", "heheda123");
formData.append("nikename", "2019-7-10");
// HTML 文件類型input,由用戶選擇
formData.append("icon", this.refs.f1.files[0]);
fetch(
`/mock/reg`,
{
method:'POST', //默認get
// body:params//{username:'alex',password:'alex123'}//URLSearchPrams
body:formData
}
).then(
res => res.json()
).then(
data => console.log(data)
)
}
}
ReactDom.render(
<App/>,
document.querySelector('#app')
);