基于antd的后台管理系统数据接口对接
一、在src目录下创建的api.js文件,里面写你需要对的接口,api文件名取名最好规范一点
import { stringify } from 'qs';//这里都是固定的
import request from '../utils/request';//这里都是固定的
// 接口调用
// 更新
export async function upCategorySet(params) {
return request(`/api/user/city/CategorySet/update`, {
method: 'PUT',
body: params,
});
}
// 添加
export async function addCategorySet(params) {
return request(`/api/user/city/CategorySet/store`, {
method: 'POST',
body: params,
});
}
// 获取数据
export async function getRecordList(params) {
return request(`/api/user/marketAction/getRecordList?${stringify(params)}`, {
method: 'GET',
});
}
// 获取数据
export async function getRecordList(params) {
return request(`/api/user/marketAction/getRecordList?${stringify(params)}`);
}
// 删除
export async function delCategorySet(params) {
return request(`/api/user/city/CategorySet/destroy`, {
method: 'DELETE',
body: params,
});
}
复制代码
以上是调接口的方式,默认情况下是get请求,get请求可以直接写接口,因为$后面是发送请求携带的参数。
二、在models层下面创建一个文件夹,文件夹下面创建一个.js文件,如cityInformation/cityInformation,其实取名也是有规范的。
import { message } from 'antd';
import {
getRecordList,
delCategorySet,
} from '../../services/cityInformation'; //cityInformation就是api文件,{}里面的内容就是接口名
export default {
namespace: 'cityInformation',//命名空间,与文件名最好一直,方便其他地方直接调用
state: { // 初始数据
msg: null,
data: {},
},
// 一定要有一个effects还有一个reducers
// effects里面放接口
// reducers里面放接口返回的数据
effects: {
*getRecordList({ payload }, { call, put }) {//*后面的名字与call的第一个参数一致,这里可以说就是真正的接口吧
const response = yield call(getRecordList, payload); // payload调接口所需的数据
yield put({
type: 'dataState', //获取的数据存在dataState
payload: response, // 返回的数据
});
return response; // response就是code msg 的返回,告诉调用接口是否成功,其实这里就是一个promise ,在下面有.then
},
*delCategorySet({ payload }, { call, put }) {
const response = yield call(delCategorySet, payload);
yield put({
type: 'dataState',
payload: response,
});
return response;
},
reducers: {
msgState(state, action) { //除了获取数据不放在这里,其他接口都要写在这里,其他接口返回的数据都放在msgState里面
let { msg } = action.payload;
if (!msg) {
msg = JSON.parse(action.payload).msg;
}
if (typeof msg !== 'string') {
msg = '操作失败';
}
message.info(msg);
return {
...state,
msg,
};
},
dataState(state, action) {//只供获取数据的接口,返回的数据存储在dataStat里面,state里面就是旧的值,这里就是初始值
const { data } = action.payload; // action就是个对象,里面有很多东西,获取到的data从中解构出来
return {
...state, //获取到的data会覆盖初始值state里面的data
data,
};
},
},
所以,reducers里面只要写一个 msgState以及一个dataState
复制代码
在我的认知里面,models下面的这个文件就是把接口封装一下,方便其他地方调用
三、到达src/common/router.js文件下面找到具体页面,从浏览器地址栏复制路由,直接搜索,如下
'/cityInformation/citySetting': { //浏览器地址路由
component: dynamicWrapper(app, ['chart'], () =>
import('../routes/CityInformation/CitySetting/CitySetting')//看这个地址找到roters目录下具体页面
),
},
// 里面chart是一个参数,这就跟命名空间有关系啦,下面就跟我们接口页面联系起来啦
// 如果在model里面没有文件夹包着,chart就写成'cityInformation'
// 如果这个页面的多个接口写在不同的Models里面,直接在[]里面加就行
'/cityInformation/citySetting': { //浏览器地址路由
component: dynamicWrapper(app, ['cityInformation/cityInformation'], () =>
import('../routes/CityInformation/CitySetting/CitySetting')//看这个地址找到routers目录下具体页面
),
},
复制代码
四、找到具体页面啦,接口调用就从这里开始啦
第一步
// 后面会用到
const getValue = obj =>
Object.keys(obj)
.map(key => obj[key])
.join(',');
// 建立连接
@connect(({ cityInformation, loading }) => ({ //@connect就是装饰器,注意,这里面有三个地方都有命名空间
cityInformation,
loading: loading.models.cityInformation,
}))
// 装饰器作用就是把当前页面与接口正式联系起来啦
// 如果当前页面调用的接口存在另外一个models层里的文件,直接在后面加,除了loading: loading.models.cityInformation,不变
@Form.create()
复制代码
第二步
// 定义初始值
export default class UserManagement extends PureComponent {
state = { //state里面就是初始值,调接口携带的参数数据也是从这里获取的
id:null,
newVisible: false,
visible: false,
selectedRows: [],//选中的某一条数据
formValues: {},
page: 1,
pageNum: 10,
data: { //所有数据都是以数组的形式包着的,每组里面有很多数据
list: [],
pagination: {//定义页码
current: 1, //当前页
pageSize: 10,//每页的条数
total: 0,//总的数据条数
},
},
};
复制代码
第三步
// 其实获取数据的接口不一定要写在生命周期函数里,只是我个人习惯
componentDidMount() {
const { page, pageNum } = this.state;//page, pageNum是从state里面解构出来的
const { dispatch } = this.props; //dispatch这才是调接口的方法,从props里面解构出来的
const later = dispatch({ //这里开始调接口啦,封装成一个函数
type: 'cityInformation/getUserLists',// 这里就是 命名空间/*后面的名字
payload: { // 参数以对象的形式书写 原本page:page,这里写成page,减少代码量
page,
page_num: pageNum,
},
});
later.then(() => {//因为调用了数据接口,数据货地了,页面数据更新
const {
cityInformation: { data },
} = this.props; //data是获取的数据,后台返回的,数据获取到了,更新页面
this.setState({
data: {
list: data.lists,
pagination: {
current: page,
pageSize: pageNum,
total: data.total,
},
},
});
});
}
复制代码
第四步
// 页面刷新,数据也会重新获取
handleStandardTableChange = (pagination, filtersArg, sorter) => {
const { formValues } = this.state;
const filters = Object.keys(filtersArg).reduce((obj, key) => {
const newObj = { ...obj };
newObj[key] = getValue(filtersArg[key]);
return newObj;
}, {});
const params = {
currentPage: pagination.current,
pageSize: pagination.pageSize,
...formValues,
...filters,
};
if (sorter.field) {
params.sorter = `${sorter.field}_${sorter.order}`;
}
// 因为pagination发生变化的话,页面会刷新,数据会重新获取,所以会调用接口
this.setState(
{
page: pagination.current,
pageNum: pagination.pageSize,
},
() => {
this.componentDidMount();
}
);
};
复制代码
handleSelectRows = rows => { //选中某行获取某行的数据
this.setState({
selectedRows: rows,
});
};
复制代码
第五步
// 页面渲染
render() {
const { loading } = this.props;
const { selectedRows } = this.state;
// 下面{}里面的dataIndex一定要与接口返回的属性名一致
const columns = [
// 正常情况下跟id这里一样写的
{
title: 'ID',
dataIndex: 'id',
},
// img 写成标签才能显示,因为ing返回的是一个图片地址
// text 是当前dataIndex对应的值,record是整条数据所有的值
{
title: '头像',
dataIndex: 'headimg',
render: (text, record) => (
"头像" style={{ width: 30, height: 30 }} />
),
},
{
title: '昵称',
dataIndex: 'name',
render: (text, record) => {record.tc_user.name},
},
{
title: '内容',
dataIndex: 'content',
},
{
title: '已拉黑',
dataIndex: 'is_black',
render: text => {text === 0 ? '未拉黑' : '已拉黑'},
},
{
title: '分类',
dataIndex: 'category',
render:(text)=>(
{text.name}
),
},
// 返回的菜品是一个数组,里面单独的一项是text ,map一定要一个key,key里面的值保证唯一就行
{
title: '菜品列表',
dataIndex: 'cart',
render:(arr)=>{
return arr.map((text)=>({text}
))
},
},
// 返回的是一个对象
{
title: '配送地址',
dataIndex: 'address',
render:(text)=>(
{text.userName}
{text.telNumber}
{text.provinceName+text.cityName+text.countyName+text.detailInfo}
//拼接
),
},
// 三元运算
{
title: '是否显示',
dataIndex: 'is_show',
render:(text)=>(
{ text === 1? '显示' : '隐藏'}
),
},
{
title: '操作',
dataIndex: 'operation',
render: (text,obj) => ( // obj 就是个参数,写成record也行
{obj.is_black === 0 ? : }
),
},
];
const { data } = this.state;//在此时data已经获取了,存在state里面
return (
"用户管理">
"id" //这个一定要写,每条数据都有一个id
selectedRows={selectedRows}
loading={loading}
data={data}//这是的data是上面解构出来的,因为要呈现在页面上
columns={columns}
onSelectRow={this.handleSelectRows}
/>
);
}
复制代码
步骤 dispatch -> effects -> api.js -> reducers,这是我自己的理解
以上都是根据我自己理解所整理的,作为一个前端菜鸟,刚学会调接口,所有的东西都带有我自己个人理解的方式,希望这篇文章能对于有需要的的朋友带来一定的帮助,同时也希望前辈们指出我的不足,我会继续努力的。