欢迎光临
我们一直在努力

AntDesignProV5从服务器请求菜单(typescript版)

【前言】

找了很多Admin模板,最后还是看中了AntDesignPro(下文简写antd pro)这个阿里巴巴开源的Admin框架,长这样(还行吧,目前挺主流的):

官网地址:https://pro.ant.design/index-cn

AntDesignProV5从服务器请求菜单(typescript版)

该套模板是使用了React开发框架作为基础,AntDesign(蚂蚁金服开源UI组件库)作为UI库,集成了Dva,Umi,Mock等库,如果不是很了解这些内容,门槛还是比较高的。

我们今天需要实现一个需求:将Antd Pro模板中固定写死的菜单换成从服务器请求菜单然后进行渲染

为啥非要自己写,官网文档不香吗?----官方文档写的实在太草了,而且目前没有typescript方式的文档,需要踩多少坑...不过没关系,看完这篇坑就都基本填平了

关于Antd Pro第一步,如何创建并运行Antd Pro,可以移步 https://www.cnblogs.com/7tiny/p/13444963.html

【了解项目中的dva和Umi用法】

antd pro 默认采用了Umi和dva组件,因此想要在基础上添加功能必须了解数据请求和数据流向

在dva中主要分3层,models,services,components,其中models是最重要概念,这里放的是各种数据,与数据交互的应该都是在这里。services是请求后台接口的方法。components是我们编写的组件。

service层

service 层仅仅是封装了用request请求服务端的api的逻辑,这里不涉及业务逻辑,比较简单,例如下面代码:

import request from '@/utils/request'; export interface LoginParamsType { userName: string; password: string; mobile: string; captcha: string; } export function fakeAccountLogin(params: LoginParamsType) { return request('/api/login/account', { method: 'POST', data: params, }); } export async function getFakeCaptcha(mobile: string) { return request(`/api/login/captcha?mobile=${mobile}`); } 

models层

models层是核心业务逻辑的所在

import { Effect, Reducer } from 'umi'; import { queryCurrent, query as queryUsers } from '@/services/user'; export interface CurrentUser { avatar?: string; name?: string; title?: string; group?: string; signature?: string; tags?: { key: string; label: string; }[]; userid?: string; unreadCount?: number; } export interface UserModelstate { currentUser?: CurrentUser; } //定义接口 export interface UserModelType { namespace: 'user'; state: UserModelState; effects: { fetch: Effect; }; reducers: { saveCurrentUser: Reducer<UserModelState>; }; } const UserModel: UserModelType = { //命名空间,component层调用路由方法的时候需要根据命名空间匹配 namespace: 'user', //存放值的地方 state: { currentUser: {}, }, // 与后台交互,处理数据逻辑的地方 effects: { //业务方法,这里的_是不需要参数,如果需要参数,这里改成传递进来的参数对象即可 //这里支持call,put,select等几种方法,用call调用service层的方法 //const m = yield select((state) => state.test.num) //select就是用来选择上面state里的,这里没用上 *fetch(_, { call, put }) { //queryUsers是引入service层那个function的一个名字 const response = yield call(queryUsers); yield put({ // 这就是reducer中save方法, put就是用来触发reducer的方法,payload里就是传过去的参数。 同时它也能触发同等级effects中其他方法。 type: 'saveCurrentUser', payload: response, }); }, }, // 能改变界面的action应该放这里,这里按官方意思不应该做数据处理,只是用来return state 从而改变界面 reducers: { //可以理解为一个方法 saveCurrentUser(state, action) { //return新的state,这样页面就会更新 es6语法,就是把state全部展开,然后把currentUser重新赋值 return { ...state, currentUser: action.payload || {}, }; }, }, }; export default UserModel; 

component组件中调用model层

在某一个方法里用dispatch即可调用

clickHandler = () => { dispatch({ type: "user/fetch",// 这里就会触发models层里面effects中fetch方法(也可以直接触发reducer中方法,看具体情况) ,user是命名空间名字 payload: { }, }) } 

这里注意一下type请求的方法路由即可,前面是命名空间,后面是方法名

使用connect获取dispatch调用后改变的state中的数据

首先需要在组件接口中定义字段,类型为model中定义的类型,因为要获取model中字段这个值,肯定是同一种类型的

AntDesignProV5从服务器请求菜单(typescript版)

然后在组件的实现中定义变量,从props中获取值

AntDesignProV5从服务器请求菜单(typescript版)

在组件代码下方的connect方法中将变量赋值,只有这里赋值了,组件中的常量才可以从props中获取到state中的值

AntDesignProV5从服务器请求菜单(typescript版)

这里connect方法的参数其实就是各个model中的state,dispatch后,这里便可以获取到修改后的值

tips:因为使用的是typescript,所以这里的参数需要在ConnectState中先定义:

AntDesignProV5从服务器请求菜单(typescript版)

【开始改造Antd Pro,实现从服务器请求菜单】

定义service

在src/services文件夹下新增文件 menu.ts

import request from '@/utils/request'; export async function query(): Promise<any> { return request('/api/getmenu'); //这里是服务端的获取菜单的地址,根据自己情况进行调整 } 

定义model

在src/models文件夹下新增文件 menu.ts

import { Effect, Reducer } from 'umi'; import { MenuDataItem } from '@ant-design/pro-layout'; import { query } from '@/services/menu'; export interface MenuModelState { menuData: MenuDataItem[]; } export interface MenuModelType { namespace: 'menu'; state: MenuModelState; effects: { getMenuData: Effect; }; reducers: { saveMenuData: Reducer<MenuModelState>; }; } //这里做了个转换,可能服务端返回的接口格式和前端的路由格式并不一致,可以在这个方法里进行调整,这里的方法仅作参考,根据自己实际情况进行调整即可 const menuFormatter = (response: any) => { if (response === null) return []; var re = response.map((item: { name: string; route: string; children: any; }) => { const result = { children: {}, name: item.name, path: item.route === null ? '/' : item.route, }; if (item.children) { result.children = menuFormatter(item.children); } return result; }) return re; } const MenuModel: MenuModelType = { namespace: 'menu', state: { menuData: [], }, effects: { *getMenuData(_, { put, call }) { const response = yield call(query); yield put({ type: 'saveMenuData', payload: menuFormatter(response.data.viewMenu), }); }, }, reducers: { saveMenuData(state, action) { return { ...state, menuData: action.payload || [], }; }, }, }; export default MenuModel; 

调整组件 BasicLayout.tsx

antd pro的菜单调整在 src/layouts/BasicLayout.tsx 文件中

AntDesignProV5从服务器请求菜单(typescript版)

这里menuDataRender 默认指向一个方法,我这里不要原来的方式,我们要调整成自己的数据

以下代码如无特殊说明,都在 BasicLayout.tsx 文件中

1. 调整接口

在 BasicLayoutProps 接口中添加承载菜单的字段

AntDesignProV5从服务器请求菜单(typescript版)

2. 调整组件传入的字段,useEfect方法中加入请求服务的路由

AntDesignProV5从服务器请求菜单(typescript版)

AntDesignProV5从服务器请求菜单(typescript版)

4. 调整connect方法,获取数据

AntDesignProV5从服务器请求菜单(typescript版)

menu是我们在models/menu.tx中定义的MenuModelState类型,光这里写会提示错误,我们需要在ConnectState中先将该字段定义才可以正常使用

AntDesignProV5从服务器请求菜单(typescript版)

【运行一下试试效果】

执行命令运行一下看看效果

cnpm start 

可以看到,已经自动触发了后端接口,并获取到了数据,最后又用服务端的数据渲染了菜单

AntDesignProV5从服务器请求菜单(typescript版)

其他内容可以参考官方文档

antd pro官网地址:https://pro.ant.design/index-cn

  • 海报
海报图正在生成中...
赞(0) 打赏
声明:
1、本博客不从事任何主机及服务器租赁业务,不参与任何交易,也绝非中介。博客内容仅记录博主个人感兴趣的服务器测评结果及一些服务器相关的优惠活动,信息均摘自网络或来自服务商主动提供;所以对本博客提及的内容不作直接、间接、法定、约定的保证,博客内容也不具备任何参考价值及引导作用,访问者需自行甄别。
2、访问本博客请务必遵守有关互联网的相关法律、规定与规则;不能利用本博客所提及的内容从事任何违法、违规操作;否则造成的一切后果由访问者自行承担。
3、未成年人及不能独立承担法律责任的个人及群体请勿访问本博客。
4、一旦您访问本博客,即表示您已经知晓并接受了以上声明通告。
文章名称:《AntDesignProV5从服务器请求菜单(typescript版)》
文章链接:https://www.456zj.com/5951.html
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址