代码重构
让代码放在更适合它的位置,使得项目更容易实现代码复用,也更加容易维护。
我们现在的代码 ./src/models/hero.js
*fetch({ type, payload }, { put, call, select }) {const data = yield request('/api/herodetails.json', { ---step1method: 'POST',headers: { ---step2Accept: 'application/json','Content-Type': 'application/json; charset=utf-8',},body: JSON.stringify({ ---step3ename: 110,}),});const localData = [ ---step4{ename: 105,cname: '廉颇',title: '正义爆轰',new_type: 0,hero_type: 3,skin_name: '正义爆轰|地狱岩魂',},{ename: 106,cname: '小乔',title: '恋之微风',new_type: 0,hero_type: 2,skin_name: '恋之微风|万圣前夜|天鹅之梦|纯白花嫁|缤纷独角兽',},];yield put({type: 'save',payload: {heros: data || localData,},});},
- step1 将接口地址散乱地写在models代码中,不便于维护,也不便于接口变动
- step2 请求设置的headers,应该是通用的,除了特殊接口需要单独设定请求头,其他的应该都是一样的
- step3 所有的post请求的body,都要进行JSON.stringify
- step4 静态数据,已经放在mock中了,这里不再需要
请求相关的都放到./src/utils/request.js
```diff export default function request(url, options) {
- if(options.method === ‘POST’){
- options.headers = {
- Accept: ‘application/json’,
- ‘Content-Type’: ‘application/json; charset=utf-8’,
- …options.headers,
- }
- options.body = JSON.stringify(options.body);
- }
return fetch(url, options).then(response => {
const resData = response.json();
return resData;
}).catch(e=>{
console.log(e)
});
}
```
我们又对这个文件进行了优化,但要用到实际生产中,它还远远不够。我们会在后续的教程中不断地完善和丰富它。所以如果,你现在就要将它用于生产环境,建议你拷贝ant-design-pro 的request文件。
接口相关的都放到./src/services/hero.js
```javascript import request from ‘../utils/request’;
export async function queryHeroList() { return request(‘/api/herolist.json’); } export async function getHeroDetails(params) { return request(‘/api/herodetails.json’, { method: ‘POST’, body: params, }); }
## ./src/models/hero.js```javascript- import request from '../utils/request';+ import { queryHeroList, getHeroDetails } from '../services/hero';...*fetch({ type, payload }, { put, call, select }) {const herolist = yield call(queryHeroList);const herodetails = yield call(getHeroDetails, { ename: 110 });console.log(herodetails);yield put({type: 'save',payload: {heros: herolist,},});},
这样models就变得很干净了,也很好理解,这里的yield call是指等待调用某个函数执行完毕。 到这里我们已经写了一些比较良好的代码,来实现了英雄页面的数据初始化。
接口统一管理
现在我们参考之前的步骤,来取得局内布局的初始化数据。
我们会同步增加 ./mock/item.js 和 ./services/item.js 文件,把文件细粒化确实便于项目的管理,但是我们总共就那么几个接口,这么做就没什么必要。所以我们修改文件名 ./mock/hero.js ==> ./mock/api.js , ./services/hero.js ==> ./services/api.js
这样子其他页面的接口,就可以统一管理了。
./mock/api.js
import herolist from './herolist.json';import item from './item.json';import summoner from './summoner.json';import ming from './ming.json';export default {'/api/herolist.json': herolist,'POST /api/herodetails.json': (req, res) => {const { ename } = req.body;const hero = herolist.filter(item => item.ename === parseInt(ename, 10))[0];res.send(hero);},'/api/item.json': item,'/api/summoner.json': summoner,'/api/ming.json': ming,};
./services/api.js
import request from '../utils/request';export async function queryHeroList() {return request('/api/herolist.json');}export async function getHeroDetails(params) {return request('/api/herodetails.json', {method: 'POST',body: params,});}export async function queryItem() {return request('/api/item.json');}export async function querySummoner() {return request('/api/summoner.json');}export async function queryMing() {return request('/api/ming.json');}
现在感觉是不是比较工整和规范啦,你可以在获得接口文档之后优先编写这两个文件,这样就实现了一个前端数据服务,后续你自己或者其他协作成员,可以直接发起http请求,而不再理会数据模拟。
代码回顾:这节课的全部代码
