项目搭建 react+antd+umi
- 用umi创建项目
npm create @umijs/umi-app
- 目录结构
- 封装网络请求工具类
import { extend } from 'umi-request';
import { notification, message } from 'antd';
type Msg = {
[key: number]: string
}
const codeMessage: Msg = {
200: '服务器成功返回请求的数据。',
201: '新建或修改数据成功。',
202: '一个请求已经进入后台排队(异步任务)。',
204: '删除数据成功。',
400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
401: '用户没有权限(令牌、用户名、密码错误)。',
403: '用户得到授权,但是访问是被禁止的。',
404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
406: '请求的格式不可得。',
410: '请求的资源被永久删除,且不会再得到的。',
422: '当创建一个对象时,发生一个验证错误。',
500: '服务器发生错误,请检查服务器。',
502: '网关错误。',
503: '服务不可用,服务器暂时过载或维护。',
504: '网关超时。',
};
const errorHandler = (error: { response: Response }): Response => {
const { response } = error;
if (response && response.status) {
const errorText = codeMessage[response.status] || response.statusText;
const { status, url } = response;
notification.error({
message: `请求错误 ${status}: ${url}`,
description: errorText,
});
} else if (!response) {
notification.error({
description: '您的网络发生异常,无法连接服务器',
message: '网络异常',
});
}
return response || {};
};
const request = extend({
// prefix:"http://localhost:8080/",
timeout: 2000,
headers: {
'Content-Type': 'application/json;charset=UTF-8',
},
errorHandler,
});
/**
* 处理响应/请求入参数据,删除返回值为null的数据,避免结构赋值出现问题
* @param response
*/
const handleResponseData = (response: object) => {
if (!response || typeof response !== 'object') {
return {};
}
// JSON.stringify(response) 可直接删除属性值为undefined的属性
const data = JSON.parse(JSON.stringify(response), (k, v) => {
if (v === null) {
return undefined;
}
return v;
});
if (!data) {
return {};
}
return data;
};
// request拦截器, 改变url 或 options.
request.interceptors.request.use((url, options) => {
// todo do something
return {
url,
options,
};
});
request.interceptors.response.use(async (response: Response) => {
const res = await response.clone().json();
const { msg, code } = res;
if (code !== 200) {
message.warning(msg);
} else {
const data = handleResponseData(res);
data.success = true
return data;
}
return response;
});
export default request;
- 网络请求的类型定义
declare namespace API{
// 这是通用的返回类型
type R<T> = {
code?:number,
msg?:string,
data?:T
}
// 这是分页数据
type page<T> = {
curPage?:number,
totalCount?:number,
list?:T[]
}
// 商品分类
type Category = {
id?:number,
pid?:number,
name?:string,
unit?:string,
avatar?:string,
count?:number,
subList?:Category
}
}
- 搭建首页框架
antd 上搜索 layout 布局,找到需要的布局,查看代码
复制到layouts/index
文件中,因为我们在配置文件中指定了 跟路径对应的页面是 layouts 下的index,所以这个布局就写在index里
再搜索menu
导航菜单控件, 点击menu就会改变路由,然后被路由监听到
主体layout , children就是路由的子组件,会被放在content中
至此 前端页面框架搭建完毕
实现输入根目录自动跳转到/home目录
如果在浏览器上输入根目录,应该自动跳转到home 目录,并且选中主页的选项, 可以在layout里面判断 location的path是不是 跟路径,如果是的话直接用history replace掉
搭建侧边栏,实现自动选中打开
思路: 侧边栏使用 antd 的menu组件,并且让侧边栏拥有监听路由的能力
- 使用 withRouter包装 侧边栏组件,包装了之后参数就有这几个值
- 在使用了withrouter之后,在引用这个组件的地方遇到了ts错误
- 修改使用方式为这样就不会了.
- 还有更简便的方法直接使用钩子,连withrouter都不需要