umi如何使⽤Mock模拟数据⽤ umi 搭建的 react 项⽬中,看 package.json ⽂件,我们可以看到:
"dependencies": {
"dva": "^2.6.0-beta.6",
"antd": "^3.19.5",
"react": "^16.8.6",
"react-dom": "^16.8.6"
},
其实 umi 中就使⽤了 dva 。
先看⼀下⽬录结构,我会标注出需要⽤到的⽂件:
├── dist/ // 默认的 build 输出⽬录
├── mock/ // mock ⽂件所在⽬录,基于 express
├── config/
├── config.js // umi 配置,同 .umirc.js,⼆选⼀
└── src/ // 源码⽬录,可选
├── layouts/index.js // 全局布局
├── models // 全局的数据仓库类似于 redux
├── pages // 页⾯⽬录,⾥⾯的⽂件即路由
├── myPage // 我创建的第⼀个⽂件夹
├── index.js // ⼊⼝⽂件
├── index.less
└── model.js // 页⾯级别的数据仓库,相当于页⾯级别的 redux
├── .umi // dev 临时⽬录,需添加到 .gitignore
├── .umi-production // build 临时⽬录,会⾃动删除
├── document.ejs // HTML 模板
├── 404.js // 404 页⾯
├── page1.js // 页⾯ 1,任意命名,导出 react 组件
├── st.js // ⽤例⽂件,umi test 会匹配所有 .test.js 和 .e2e.js 结尾的⽂件
└── page2.js // 页⾯ 2,任意命名
├── services
└── api.js // *放接⼝
├── utils
├── config.js // *配置路径
└── request.js // *封装 fetch ⽅法
├── global.css // 约定的全局样式⽂件,⾃动引⼊,也可以⽤ global.less
├── global.js // 可以在这⾥加⼊ polyfill
├── app.js // 运⾏时配置⽂件
├── .umirc.js // umi 配置,同 config/config.js,⼆选⼀
├── .env // 环境变量
├── .gitignore // 避免将不必要的代码提交到 git 仓库中
└── package.json
如果你做的是⼀个新项⽬,请不要跳过第⼀步。
⼀、fetch 请求简单的封装
1、在 utils ⽂件夹下创建 config.js ⽂件,utils/config.js,对fetch请求路径进⾏配置
//config.js⽂件
const config = {
apiUrl: v.NODE_ENV === 'development' ? ' 127.0.0.1:7001' : 'www.baidu',
apiPrefix: ' 127.0.0.1:7001',
proxy: true//是否开启mock代理
};
export default config;
2、简单封装 fetch 请求,utils⽂件夹下的 request.js ⽂件
//request.js⽂件
import fetch from 'dva/fetch';
import config from './config';
function parseJSON(response) {
return response.json();
}
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
}
const error = new Error(response.statusText);
throw error;
}
const assyParams = (obj) => {
let str = ''
for (let key in obj) {
const value = typeof obj[key] !== 'string' ? JSON.stringify(obj[key]) : obj[key]
str += '&' + key + '=' + value
}
return str.substr(1)
}
/**
* Requests a URL, returning a promise.
*
* @param {string} url The URL we want to request
* @param {object} [options] The options we want to pass to "fetch"
* @return {object} An object containing either "data" or "err"
*/
export default function request(obj) {
let url = '';
let options = {
method: hod,
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
credentials: 'include' //是否携带cookie,默认为omit不携带; same-origi同源携带; include同源跨域都携带 };
if (hod === 'GET' || hod === 'get') {
url = (config.proxy ? obj.url : config.apiUrl + obj.url) + '?' + assyParams(obj.data);
}
if (hod === 'POST' || hod === 'post') {
url = config.proxy ? obj.url : config.apiUrl + obj.url;
options.body = JSON.stringify(obj.data);
}
return fetch(url, options)
.then(checkStatus)
.then(parseJSON)
.then(data => ({ data }))
.
catch(err => ({ err }))
}
⼆、写 api
1、service ⽂件下创建 api.js
import request from '../utils/request';
export function getSomeData(params) {
return request({
method: "GET",
url: `/appservice/common/v1/getSomeData`,
data: JSON.stringify(params),
})
}
三、mock 相关配置
1、在 mock ⽂件夹下新建 someData.js ⽂件(⽂件名看⼯作需要修改)
const responseData = {
status: 'ok',
code: 200,
data: "这是数据"
}
export default {
// ⽀持值为 Object 和 Array
'GET /appservice/common/v1/getSomeData': responseData,
/
/ GET POST 可省略⽐如:
'/api/users/1': { id: 1 },
}
四、编写 src/pages/myPage/model.js
/*
export default {
namespace: '', // 表⽰在全局 state 上的 key
state: {}, // 状态数据
reducers: {}, // 管理同步⽅法,必须是纯函数
effects: {}, // 管理异步操作,采⽤了 generator 的相关概念
subscriptions: {}, // 订阅数据源
};
call: 执⾏异步函数
put: 发出⼀个 Action,类似于 dispatch
select: 返回 model 中的 state
*/
import {
getSomeData,
} from '../../services/api';
function initState() {
return {
modelNum: 0,
text: "没有返回"
js获取json的key和value};
}
export default {
namespace: 'myPage', // 表⽰在全局 state 上的 key
state: initState(), // 状态数据
effects: { // 管理异步操作,采⽤了 generator 的相关概念
*getSomeData({ payload }, { call, put, select }) {
const res = yield call(getSomeData, payload);
if (de === 200) { // 拿到数据,可以选择存到 model 中
yield put({
type: 'saveDefault',
payload: {
text: res.data.data
},
});
}
return res;
},
},
reducers: { // 管理同步⽅法,必须是纯函数
saveDefault(state, action) {
return {
...state,
...action.payload,
};
},
resetState() { // 重置 state
return initState();
},
},
};
五、调⽤api发送请求
1、例如在 src/pages/myPage/index.js 页⾯发送请求,并在页⾯中显⽰请求到的数据
2、如果在第4步中,选择将接⼝返回的数据存在 model 中,此页⾯就可以直接从 model 中获取数据,不需要存到 state 中import React, { Component } from "react";import { Button } from 'antd';import { connect } from 'dva';
import { connect } from 'react-redux';
class secondPage extends Component {
constructor(props) {
super(props);
this.state = {
data: null
}
}
getSomeData = async () => {
const { dispatch } = this.props;
await dispatch({
type: 'myPage/getSomeData'
}).then((res) => {
if (res && res.data && de === 200) {
this.setState({ // 这⾥选择将数据存在 state 中,也可以从 model 中获取
data: res.data.data
})
}
})
}
render() {
const { data } = this.state;
return (
<div>
<div>
<span>异步请求的返回:{data || "--"}</span>
<Button onClick={() => SomeData()} >请求接⼝</Button>
</div>
</div>
)
}
}
const mapStateToProps = (model) => {
console.log(model) // 查看 props 中的数据,可以拿到存在 model 中的数据。
// return 出来的数据,会被添加到对应的 props 中
};
export default connect(mapStateToProps)(secondPage)
/*
拿到 dispatch 的⼏种⽅式
import { useDispatch } from 'react-redux';
import { useDispatch } from 'dva';
export default function (props) {
const dispatch = useDispatch();
return (
<div>
</div>
);
}
*/
结尾:对于⼀个没⼈教的菜鸟来说,摸索出这⼀套,真的相当费劲,断断续续的隔了好⼏周,终于完成了。此⽂章复制可⽤,如果对你也有⽤,请⼀定要让我知道,万分感谢。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论