mock官网的介绍:生成随机数据,拦截 Ajax 请求。使用mock生成模拟数据有这样的好处:
mock官网的介绍:生成随机数据,拦截 Ajax 请求。使用mock生成模拟数据有这样的好处:
❄让前后端分离,可以在不使用接口的时候也能生成动态数据。
❄防止第三方接口失效,在调用第三方接口的时候,今天还开着,有可能明天就被关了/(ㄒoㄒ)/~~。所以可以使用mock-server来模拟接口返回数据。
类似mock的还有百度的 yapi,阿里的 rap2, 大搜车的 easy-mock
本文将使用三种方法来请求mock,一种直接调用axios中的方法,一种原生的promise+xhr,一种在前面的基础上使用async/ await。
附上demoGitHub的地址
安装依赖
1 2
| yarn add mockjs yarn add axios
|
文件目录
|—data.js
|—mock.js
|—index.js
data中设置mock的请求路径,请求方法,还有一些模拟数据。mock作为组件发送请求,需要注意的是data需要挂载到index上,不然mock访问不到的。index是入口文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| //data.js import Mock from 'mockjs' export default Mock.mock(/getdata/,'get',{ success:true, message:'@image', 'list|1-3': [{ // 属性 sid 是一个自增数,起始值为 1,每次增 1 'sid|+1': 1, // 属性 userId 是一个5位的随机码 'userId|5': '', // 属性 sex 是一个bool值 "sex|1-2": true, // 属性 city对象 是对象值中2-4个的值 "city|2-4": { "110000": "北京市", "120000": "天津市", "130000": "河北省", "140000": "山西省" }, //属性 grade 是数组当中的一个值 "grade|1": [ "1年级", "2年级", "3年级" ], //属性 guid 是唯一机器码 'guid': '@guid', //属性 id 是随机id 'id': '@id', //属性 title 是一个随机长度的标题 'title': '@title()', //属性 paragraph 是一个随机长度的段落 'paragraph': '@cparagraph', //属性 image 是一个随机图片 参数分别为size, background, text 'image': "@image('200x100', '#FFC0CB', 'Hello')", //属性 address 是一个随机地址 'address': '@county(true)', //属性 date 是一个yyyy-MM-dd 的随机日期 'date': '@date("yyyy-MM-dd")', //属性 time 是一个 size, background, text 的随机时间 'time': '@time("HH:mm:ss")', //属性 url 是一个随机的url 'url': '@url', //属性 email 是一个随机email 'email': '@email', //属性 ip 是一个随机ip 'ip': '@ip', //属性 regexp 是一个正则表达式匹配到的值 如aA1 'regexp': /[a-z][A-Z][0-9]/, }] })
|
使用axios来发送请求
axios是一个基于promise的跨浏览器和nodejs的HTTP客户端,在这里使用get方法来发送请求,获取数据。写在componentDidMount中,当React插入组件到DOM后,里面的方法被调用一次。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import React from 'react' import axios from 'axios' class Mock extends React.Component { constructor(props) { super(props) this.state = { gData: null } } componentDidMount() { this.getData() } getData = () => { axios.get('/getdata', { params: { image: ('200x100', '#FFF', 'Mock.js') } }) .then((res) => { this.setState({ gData: res.data.message }) }) .catch((err) => { console.log(err) }) } render() { return ( <div> <img src={this.state.gData} /> <button onClick={this.getData}>点击获取(Get)Mock数据</button> </div> ) } } export default Mock
|
不过一开始,在这里报了一个错:
1 2 3
| Failed to compile src\mock.js Line 14:5: 'getData' is not defined no-undef
|
因为我是这样写的。。。。
1 2 3 4 5
| componentDidMount() { getData = () => { ... } }
|
在componentDidMount中直接写方法报错的原因不太清楚,不过正确的写法有两种,一种是上面直接调用this.getData方法,另一种是直接aixos.get,不过这样就只是在初始时会请求数据。
使用promise+xhr来实现ajax
写这个也没有别的意思,加强一下基础💪
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| componentDidMount() { this.getData() } getData = () => { this.ajax('/getdata') .then( (res) => { this.setState({ gData: res.message }) }) .catch((err) => { console.log(err) }) } ajax = (url) => { var p = new Promise(function (res, rej) { var xhr = new XMLHttpRequest() xhr.onreadystatechange = function () { if (xhr.readyState != 4) return if (xhr.readyState == 4 && xhr.status == 200) { res(JSON.parse(xhr.response)) } else { rej('error') }} xhr.open('get', url) xhr.send(null) }) return p }
|
但是当我们需要发送多个ajax请求的时候,很多then的链式,代码有点回调地狱内味了(假设配置了/getdata1,/getdata2)
1 2 3 4 5 6 7 8 9 10 11 12 13
| getData('/getdata') .then(function(res){ console.log(res) return queryData('/getdata1'); }) .then(function(res){ console.log(res); return queryData('/getdata2'); }) .then(function(res){ console.log(res) });
|
于是我们可以用async/ await 来改造一下
async/ await
是一个用同步的思维来解决异步问题的方案,async作为一个关键词放到普通函数前,表示函数是一个异步函数,不会阻塞后面代码的执行。然后等待await后面的函数运行完并有了返回结果后,继续执行。
1 2 3 4 5 6 7 8 9 10
| getData = async () => { try{ const res=await this.ajax('/getdata') this.setState({ gData:res.message }) }catch(err){ console.log(err) } }
|
需要注意的是,async的写法,一开始我是这样写的🙅
1 2 3 4 5 6 7 8
| async getData(){ try{ ... }) }catch(err){ ... } }
|
因为还是写在了componentDidMount,所以第一次请求是可以获得数据的,但是之后点击再调用了事件,就会报会这样的错
1
| TypeError: Cannot read property 'ajax' of undefined
|
项目
在总结的过程中,被别人安利了安利 hooks,不用关注this和@umi/useRequest。下次再了解(下次一定下次一定
参考文章:
React中使用Mockjs进行接口数据模拟
React请求数据为什么要在componentDidMount方法里面做?
async/await基本理解及项目案例(结合Promise)
Mock接口依赖的使用