在 Ant Design Pro 中,一个完整的前端 UI 交互到服务端处理流程是这样的:
- UI 组件交互操作;
- 调用 model 的 effect;
- 调用统一管理的 service 请求函数;
- 使用封装的 request.ts 发送请求;
- 获取服务端返回;
- 然后调用 reducer 改变 state;
- 更新 model。
1.直接发送请求得交互
适用于单页面得交互
1.1配置路由和国际化
//config/routes.ts
{
path:"/person",
icon:"UserOutlined",
name:'person',
component:'./Person'
},
//locales/zh-CN/menu.ts
'menu.person':'个人中心'
1.2配置mock数据
//mock/person.ts
export default {
'/api/person': [
{id:1,name:'tom',age:22,sex:'男'},
{id:2,name:'jack',age:16,sex:'男'},
{id:3,name:'aswe',age:20,sex:'女'},
{id:4,name:'sary',age:21,sex:'女'},
]
}
1.3sevice发送请求获取数据
//src/service/person.ts
import request from '@/utils/request';
export async function getPersonDatas() {
return request('/api/person');
}
1.4组件中使用
//src/pages/Person/index.tsx
import React, { useRef } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { PlusOutlined } from '@ant-design/icons';
import { Button} from 'antd';
import type { ActionType } from '@ant-design/pro-table';
import ProTable from '@ant-design/pro-table';
import { getPersonDatas} from "../../services/person"
const columns = [
{
title:'姓名',
dataIndex: 'name',
},
{
title:'年龄',
dataIndex: 'age',
//不开启搜索
hideInSearch:true
},
{
title:'性别',
dataIndex: 'sex',
hideInSearch:true
},
];
//获取数据
const getDatasHttp=async()=>{
const data=await getPersonDatas()
return {data}
}
const Person = () => {
const actionRef = useRef<ActionType>();
return (
<div>
<PageHeaderWrapper>
<ProTable
columns={columns}
actionRef={actionRef}
request={async (params = {}) => getDatasHttp()}
editable={{
type: 'multiple',
}}
rowKey="id"
search={{
labelWidth: 'auto',
}}
form={{
// 由于配置了 transform,提交的参与与定义的不同这里需要转化一下
syncToUrl: (values, type) => {
if (type === 'get') {
return {
...values,
created_at: [values.startTime, values.endTime],
};
}
return values;
},
}}
pagination={{
pageSize: 5,
}}
dateFormatter="string"
headerTitle="高级表格"
toolBarRender={() => [
<Button key="button" icon={<PlusOutlined />} type="primary">
新建
</Button>,
]}
/>
</PageHeaderWrapper>
</div>
)
}
export default Person
2.通过redux实现交互
适用于多个页面公用一个数据
2.1配置redux
//models/person.ts
import {getPersonDatas}from "@/services/person"
import { Effect,Reducer} from 'umi'
interface IndexModelState {
name: string;
}
interface IndexModelType {
namespace :string,
state:{
persons:any[]
},
effects: {
fetchPersons: Effect
},
reducers:{
setPersons: Reducer<IndexModelState>;
}
}
const personModel:IndexModelType={
namespace:'person',
state:{
persons:[]
},
effects:{
*fetchPersons(_,{call,put}){
const data=yield call(getPersonDatas)
yield put({
type:'setPersons',
payload:data
})
}
},
reducers:{
setPersons(state:any,action:any){
return {
...state,
persons:action.payload
}
}
}
}
export default personModel
2.2在组件中使用
//src/pages/Person/index.tsx
import React, { useRef, useEffect } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { PlusOutlined } from '@ant-design/icons';
import { Button } from 'antd';
import type { ActionType } from '@ant-design/pro-table';
import ProTable from '@ant-design/pro-table';
import { connect } from 'umi';
const columns = [
{
title: '姓名',
dataIndex: 'name',
},
{
title: '年龄',
dataIndex: 'age',
hideInSearch: true,
},
{
title: '性别',
dataIndex: 'sex',
hideInSearch: true,
},
];
//获取数据
const Person = (props: any) => {
const { dispatch }: any = props;
useEffect(() => {
//使用model,更新数据
dispatch({
//调用命名空间的某个方法
type: 'person/fetchPersons',
//需要传递的参数,这里可以传递一些发送请求所需要的参数
payload: null,
});
}, []);
const actionRef = useRef<ActionType>();
// const getDatasHttp = () => {
// const data = props.person.persons;
// return { data };
// };
return (
<div>
<PageHeaderWrapper>
<ProTable
columns={columns}
actionRef={actionRef}
// request={async (params = {}) => getDatasHttp()}
dataSource={props.person.persons}
editable={{
type: 'multiple',
}}
rowKey="id"
search={{
labelWidth: 'auto',
}}
form={{
// 由于配置了 transform,提交的参与与定义的不同这里需要转化一下
syncToUrl: (values, type) => {
if (type === 'get') {
return {
...values,
created_at: [values.startTime, values.endTime],
};
}
return values;
},
}}
pagination={{
pageSize: 5,
}}
dateFormatter="string"
headerTitle="名单管理"
toolBarRender={() => [
<Button key="button" icon={<PlusOutlined />} type="primary">
新建
</Button>,
]}
/>
</PageHeaderWrapper>
</div>
);
};
//连接ui组件和容器组件
export default connect(
//这里得person与命名空间的值保持一致
({ person }: any) => ({ person }),
)(Person);