您当前的位置:首页 > 网站建设 > React
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax | jQuery |

基于antd的后台管理系统数据接口对接

51自学网 2020-03-12 16:32:25
  React

基于antd的后台管理系统数据接口对接

一、在src目录下创建的api.js文件,里面写你需要对的接口,api文件名取名最好规范一点


 
  1. import { stringify } from 'qs';//这里都是固定的
  2. import request from '../utils/request';//这里都是固定的
  3.  
  4. // 接口调用
  5.  
  6. // 更新
  7. export async function upCategorySet(params) {
  8. return request(`/api/user/city/CategorySet/update`, {
  9. method: 'PUT',
  10. body: params,
  11. });
  12. }
  13. // 添加
  14. export async function addCategorySet(params) {
  15. return request(`/api/user/city/CategorySet/store`, {
  16. method: 'POST',
  17. body: params,
  18. });
  19. }
  20. // 获取数据
  21. export async function getRecordList(params) {
  22. return request(`/api/user/marketAction/getRecordList?${stringify(params)}`, {
  23. method: 'GET',
  24. });
  25. }
  26. // 获取数据
  27. export async function getRecordList(params) {
  28. return request(`/api/user/marketAction/getRecordList?${stringify(params)}`);
  29. }
  30. // 删除
  31. export async function delCategorySet(params) {
  32. return request(`/api/user/city/CategorySet/destroy`, {
  33. method: 'DELETE',
  34. body: params,
  35. });
  36. }
  37. 复制代码

以上是调接口的方式,默认情况下是get请求,get请求可以直接写接口,因为$后面是发送请求携带的参数。

二、在models层下面创建一个文件夹,文件夹下面创建一个.js文件,如cityInformation/cityInformation,其实取名也是有规范的。


 
  1. import { message } from 'antd';
  2. import {
  3. getRecordList,
  4. delCategorySet,
  5. } from '../../services/cityInformation'; //cityInformation就是api文件,{}里面的内容就是接口名
  6.  
  7. export default {
  8. namespace: 'cityInformation',//命名空间,与文件名最好一直,方便其他地方直接调用
  9. state: { // 初始数据
  10. msg: null,
  11. data: {},
  12. },
  13. // 一定要有一个effects还有一个reducers
  14. // effects里面放接口
  15. // reducers里面放接口返回的数据
  16. effects: {
  17. *getRecordList({ payload }, { call, put }) {//*后面的名字与call的第一个参数一致,这里可以说就是真正的接口吧
  18. const response = yield call(getRecordList, payload); // payload调接口所需的数据
  19. yield put({
  20. type: 'dataState', //获取的数据存在dataState
  21. payload: response, // 返回的数据
  22. });
  23. return response; // response就是code msg 的返回,告诉调用接口是否成功,其实这里就是一个promise ,在下面有.then
  24. },
  25. *delCategorySet({ payload }, { call, put }) {
  26. const response = yield call(delCategorySet, payload);
  27. yield put({
  28. type: 'dataState',
  29. payload: response,
  30. });
  31. return response;
  32. },
  33. reducers: {
  34. msgState(state, action) { //除了获取数据不放在这里,其他接口都要写在这里,其他接口返回的数据都放在msgState里面
  35. let { msg } = action.payload;
  36. if (!msg) {
  37. msg = JSON.parse(action.payload).msg;
  38. }
  39. if (typeof msg !== 'string') {
  40. msg = '操作失败';
  41. }
  42. message.info(msg);
  43. return {
  44. ...state,
  45. msg,
  46. };
  47. },
  48. dataState(state, action) {//只供获取数据的接口,返回的数据存储在dataStat里面,state里面就是旧的值,这里就是初始值
  49. const { data } = action.payload; // action就是个对象,里面有很多东西,获取到的data从中解构出来
  50. return {
  51. ...state, //获取到的data会覆盖初始值state里面的data
  52. data,
  53. };
  54. },
  55. },
  56. 所以,reducers里面只要写一个 msgState以及一个dataState
  57. 复制代码

在我的认知里面,models下面的这个文件就是把接口封装一下,方便其他地方调用

三、到达src/common/router.js文件下面找到具体页面,从浏览器地址栏复制路由,直接搜索,如下


 
  1. '/cityInformation/citySetting': { //浏览器地址路由
  2. component: dynamicWrapper(app, ['chart'], () =>
  3. import('../routes/CityInformation/CitySetting/CitySetting')//看这个地址找到roters目录下具体页面
  4. ),
  5. },
  6. // 里面chart是一个参数,这就跟命名空间有关系啦,下面就跟我们接口页面联系起来啦
  7. // 如果在model里面没有文件夹包着,chart就写成'cityInformation'
  8. // 如果这个页面的多个接口写在不同的Models里面,直接在[]里面加就行
  9. '/cityInformation/citySetting': { //浏览器地址路由
  10. component: dynamicWrapper(app, ['cityInformation/cityInformation'], () =>
  11. import('../routes/CityInformation/CitySetting/CitySetting')//看这个地址找到routers目录下具体页面
  12. ),
  13. },
  14. 复制代码

四、找到具体页面啦,接口调用就从这里开始啦

第一步


 
  1. // 后面会用到
  2. const getValue = obj =>
  3. Object.keys(obj)
  4. .map(key => obj[key])
  5. .join(',');
  6. // 建立连接
  7. @connect(({ cityInformation, loading }) => ({ //@connect就是装饰器,注意,这里面有三个地方都有命名空间
  8. cityInformation,
  9. loading: loading.models.cityInformation,
  10. }))
  11. // 装饰器作用就是把当前页面与接口正式联系起来啦
  12. // 如果当前页面调用的接口存在另外一个models层里的文件,直接在后面加,除了loading: loading.models.cityInformation,不变
  13. @Form.create()
  14. 复制代码

第二步


 
  1. // 定义初始值
  2. export default class UserManagement extends PureComponent {
  3. state = { //state里面就是初始值,调接口携带的参数数据也是从这里获取的
  4. id:null,
  5. newVisible: false,
  6. visible: false,
  7. selectedRows: [],//选中的某一条数据
  8. formValues: {},
  9. page: 1,
  10. pageNum: 10,
  11. data: { //所有数据都是以数组的形式包着的,每组里面有很多数据
  12. list: [],
  13. pagination: {//定义页码
  14. current: 1, //当前页
  15. pageSize: 10,//每页的条数
  16. total: 0,//总的数据条数
  17. },
  18. },
  19. };
  20. 复制代码

第三步


 
  1. // 其实获取数据的接口不一定要写在生命周期函数里,只是我个人习惯
  2. componentDidMount() {
  3. const { page, pageNum } = this.state;//page, pageNum是从state里面解构出来的
  4. const { dispatch } = this.props; //dispatch这才是调接口的方法,从props里面解构出来的
  5. const later = dispatch({ //这里开始调接口啦,封装成一个函数
  6. type: 'cityInformation/getUserLists',// 这里就是 命名空间/*后面的名字
  7. payload: { // 参数以对象的形式书写 原本page:page,这里写成page,减少代码量
  8. page,
  9. page_num: pageNum,
  10. },
  11. });
  12. later.then(() => {//因为调用了数据接口,数据货地了,页面数据更新
  13. const {
  14. cityInformation: { data },
  15. } = this.props; //data是获取的数据,后台返回的,数据获取到了,更新页面
  16. this.setState({
  17. data: {
  18. list: data.lists,
  19. pagination: {
  20. current: page,
  21. pageSize: pageNum,
  22. total: data.total,
  23. },
  24. },
  25. });
  26. });
  27. }
  28. 复制代码

第四步


 
  1. // 页面刷新,数据也会重新获取
  2. handleStandardTableChange = (pagination, filtersArg, sorter) => {
  3. const { formValues } = this.state;
  4. const filters = Object.keys(filtersArg).reduce((obj, key) => {
  5. const newObj = { ...obj };
  6. newObj[key] = getValue(filtersArg[key]);
  7. return newObj;
  8. }, {});
  9.  
  10. const params = {
  11. currentPage: pagination.current,
  12. pageSize: pagination.pageSize,
  13. ...formValues,
  14. ...filters,
  15. };
  16. if (sorter.field) {
  17. params.sorter = `${sorter.field}_${sorter.order}`;
  18. }
  19. // 因为pagination发生变化的话,页面会刷新,数据会重新获取,所以会调用接口
  20. this.setState(
  21. {
  22. page: pagination.current,
  23. pageNum: pagination.pageSize,
  24. },
  25. () => {
  26. this.componentDidMount();
  27. }
  28. );
  29. };
  30. 复制代码

 
  1. handleSelectRows = rows => { //选中某行获取某行的数据
  2. this.setState({
  3. selectedRows: rows,
  4. });
  5. };
  6. 复制代码

第五步


 
  1. // 页面渲染
  2. render() {
  3. const { loading } = this.props;
  4. const { selectedRows } = this.state;
  5. // 下面{}里面的dataIndex一定要与接口返回的属性名一致
  6. const columns = [
  7. // 正常情况下跟id这里一样写的
  8. {
  9. title: 'ID',
  10. dataIndex: 'id',
  11. },
  12. // img 写成标签才能显示,因为ing返回的是一个图片地址
  13. // text 是当前dataIndex对应的值,record是整条数据所有的值
  14. {
  15. title: '头像',
  16. dataIndex: 'headimg',
  17. render: (text, record) => (
  18. <img src={record.tc_user.headimg} alt="头像" style={{ width: 30, height: 30 }} />
  19. ),
  20. },
  21. {
  22. title: '昵称',
  23. dataIndex: 'name',
  24. render: (text, record) => <span>{record.tc_user.name}</span>,
  25. },
  26. {
  27. title: '内容',
  28. dataIndex: 'content',
  29. },
  30. {
  31. title: '已拉黑',
  32. dataIndex: 'is_black',
  33. render: text => <span>{text === 0 ? '未拉黑' : '已拉黑'}</span>,
  34. },
  35. {
  36. title: '分类',
  37. dataIndex: 'category',
  38. render:(text)=>(
  39. <span>{text.name}</span>
  40. ),
  41. },
  42. // 返回的菜品是一个数组,里面单独的一项是text ,map一定要一个key,key里面的值保证唯一就行
  43. {
  44. title: '菜品列表',
  45. dataIndex: 'cart',
  46. render:(arr)=>{
  47. return arr.map((text)=>(<span key={text}>{text}<br /></span>))
  48. },
  49. },
  50. // 返回的是一个对象
  51. {
  52. title: '配送地址',
  53. dataIndex: 'address',
  54. render:(text)=>(
  55. <div>
  56. <span>{text.userName}<br /></span>
  57. <span>{text.telNumber}<br /></span>
  58. <span>{text.provinceName+text.cityName+text.countyName+text.detailInfo}<br /></span>//拼接
  59. </div>
  60. ),
  61. },
  62. // 三元运算
  63. {
  64. title: '是否显示',
  65. dataIndex: 'is_show',
  66. render:(text)=>(
  67. <span>{ text === 1? '显示' : '隐藏'}</span>
  68. ),
  69. },
  70. {
  71. title: '操作',
  72. dataIndex: 'operation',
  73. render: (text,obj) => ( // obj 就是个参数,写成record也行
  74. <div>
  75. {obj.is_black === 0 ? <Button onClick={()=>this.shielding(obj.id,1)}>拉黑</Button> : <Button onClick={()=>this.shielding(obj.id,0)}>取消拉黑</Button>}
  76. </div>
  77. ),
  78. },
  79. ];
  80. const { data } = this.state;//在此时data已经获取了,存在state里面
  81. return (
  82. <PageHeaderLayout title="用户管理">
  83. <StandardTable
  84. rowKey="id" //这个一定要写,每条数据都有一个id
  85. selectedRows={selectedRows}
  86. loading={loading}
  87. data={data}//这是的data是上面解构出来的,因为要呈现在页面上
  88. columns={columns}
  89. onSelectRow={this.handleSelectRows}
  90. />
  91. </PageHeaderLayout>
  92. );
  93. }
  94.  
  95. 复制代码

步骤 dispatch -> effects -> api.js -> reducers,这是我自己的理解

以上都是根据我自己理解所整理的,作为一个前端菜鸟,刚学会调接口,所有的东西都带有我自己个人理解的方式,希望这篇文章能对于有需要的的朋友带来一定的帮助,同时也希望前辈们指出我的不足,我会继续努力的。


下载地址:
api接口可用
webpack+react+antd 单页面应用实例
51自学网,即我要自学网,自学EXCEL、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。
京ICP备13026421号-1