创作人 Leo
编辑时间 Mon Aug 15,2022 at 15:47
ant design pro 是蚂蚁金服开发的一款企业级前端框架
其中使用 umijs 为主体框架 文档
使用 react + JSX 为主要开发语言 docs
使用 mock 实现完全脱离后端开发 umi mock 文档 antd-pro 配置 mock 数据
使用 dva - redux 实现数据驱动实时渲染界面 dva 文档 redux 文档
使用 ant design ui 库 浏览组件
antdpro 结合了 mockjs 来实现前后端分离开发
前期在后端 api 没有完全给出,通过在 mock 文件夹中编写对应数据模型,实现伪数据填充
通过启动参数 npm run start:no-mock 可以关闭 mock 模式
关闭 mock 后,数据源会从 proxy 获取,proxy 在 config/proxy.js 中配置
注意:在生产环境 代理是无法生效的
首先编写伪数据
在 mock 文件夹建立 goods.js
const getgoods = (req, res)=>{
let list = [
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
]
res.json({list:list}) ;
}
export default {
"GET /api/goods/list" : getgoods
}
这里我们定义 GET 请求 /api/goods/list 会返回一批商品数据
通过 res.json 返回json数据
这个定义好可以通过浏览器 http://localhost:8002/api/goods/list 查看效果
然后编写 service
在 service 文件夹新建 goods.js
import request from '@/utils/request';
export async function list() {
return request('/api/goods/list');
}
这个 service 层就是一个代理,主要是方便后续开发可以调换数据源,比如切换到后端提供的 api
然后编写 model
在 models 下新建 goods.js
导入我们刚刚编写的 services/goods
*fetchCurrent + yield 实现生成器函数,这是固定写法
import { list as listGoods } from '@/services/goods';
const GoodsModel = {
namespace: "goods",
state:{
currentGoods:{}
} ,
effects: {
*fetchCurrent(_, { call, put }) {
const response = yield call(listGoods);
yield put({
type: 'saveListGoods',
payload: response,
});
},
},
reducers: {
saveListGoods(state, action) {
return { ...state, currentGoods: action.payload || [] };
},
},
}
export default GoodsModel ;
namespace model 的命名空间,同时也是他在全局 state 上的属性,只能用字符串,不支持通过 . 的方式创建多层命名空间
state 初始值,优先级低于传给 dva() 的 opts.initialState
effects 以 key/value 格式定义 effect。用于处理异步操作和业务逻辑,不直接修改 state。由 action 触发,可以触发 action,可以和服务器交互,可以获取全局 state 的数据等等。
reducers 以 key/value 格式定义 reducer。用于处理同步操作,唯一可以修改 state 的地方。由 action 触发。
开发中一般会把可复用模块单独编写成组件
组件开发具体可以参考 react 的组件章节
我们编写一个组件,让上面的商品数据能够渲染出来
在 pages 文件夹中新建 TestWaa.jsx
import React from 'react'
import { Table, Tag } from "antd";
import { history, connect } from 'umi';
const columns = [
{
title: '姓名',
dataIndex: 'name',
key: 'name',
},
{
title: '年龄',
dataIndex: 'age',
key: 'age',
},
{
title: '住址',
dataIndex: 'address',
key: 'address',
},
];
class TestWaa extends React.Component {
componentDidMount() {
const { dispatch } = this.props;
if (dispatch) {
dispatch({
type: 'goods/fetchCurrent',
});
}
}
render() {
const { currentGoods } = this.props;
return <Table dataSource={currentGoods.list} columns={columns} /> ;
}
}
export default connect(({ goods }) => ({
currentGoods: goods.currentGoods,
}))(TestWaa);
我们首先加载了几个库:
React 是基础的 react 库
Table 我们使用 Table 渲染数据
connect 我们使用 connect 将数据绑定到组件
解释下代码逻辑:
componentDidMount 熟悉 react 的小伙伴应该知道,这是让 react 在组件加载时调用 state 数据
render 中编写渲染逻辑
props 熟悉 redux 的小伙伴应该知道这是 redux 的操作句柄
goods 是我们在 mock 节提到的数据的 namespace
currentGoods 就是对应的 state 了
如果对这块不熟悉,建议先学习下 react 和 redux 基础
新建一个页面,把这个组件接进来
在 pages 中新建 TestPage.jsx 和 TestPage.less (页面文件一般会包含这两个文件,一个逻辑,一个样式)
TestPage.jsx
import React from 'react'
import BasicLayout, { PageHeaderWrapper } from '@ant-design/pro-layout';
import ImageWrapper from '@/components/ImageWrapper'; // @ 表示相对于源文件根目录
import TestWaa from './TestWaa';
export default () => (
<PageHeaderWrapper>
<TestWaa />
<ImageWrapper src="https://os.alipayobjects.com/rmsportal/mgesTPFxodmIwpi.png" desc="示意图" />
</PageHeaderWrapper>
) ;
TestPage.less
@import '~antd/lib/style/themes/default.less';
我们修改路由文件 config/config.js 将新页面加进去
在 routes 中添加
...
{
name: '测试页面',
icon: 'smile',
path: '/testpage',
component: './TestPage',
},
...
https://zh-hans.reactjs.org/docs/hooks-reference.html#usecallback
useState
最基础的 hook
返回一个 state,以及更新 state 的函数。
useEffect
该 Hook 接收一个包含命令式、且可能有副作用代码的函数。
解释一下就是阻塞UI的应该放在这个 hook 里执行,比如网络请求
默认情况下,effect 将在每轮渲染结束后执行,但你可以选择让它 在只有某些值改变的时候 才执行。
useMemo
把“创建”函数和依赖项数组作为参数传入 useMemo,它仅会在某个依赖项改变时才重新计算 memoized 值。这种优化有助于避免在每次渲染时都进行高开销的计算。
https://en.wikipedia.org/wiki/Memoization
主要用于通过存储昂贵的函数调用的结果并在再次出现相同的输入时返回缓存的结果来加速计算机程序。
useRef
useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数
使用该 hook 可以使值每次使用时都是最新的
本质上,useRef 就像是可以在其 .current 属性中保存一个可变值的“盒子”。
注意:
1. 大部分 hook 后面都会有一个 dep 列表,该 dep 列表用来控制这个 hook 只有在列表中变量值被修改的情况下执行