Ant Design Pro V5 从服务器请求菜单(typescript版)

摘要:
exportinterfaceLoginPramsType{userName:password:}exportfunctionfakeAccountLogin(参数:{method:data:mobile=${mobile}`);标记:标签:字符串;字符串:数字:select和其他方法:

【前言】

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

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

Ant Design Pro V5 从服务器请求菜单(typescript版)第1张

该套模板是使用了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中字段这个值,肯定是同一种类型的

Ant Design Pro V5 从服务器请求菜单(typescript版)第2张

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

Ant Design Pro V5 从服务器请求菜单(typescript版)第3张

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

Ant Design Pro V5 从服务器请求菜单(typescript版)第4张

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

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

Ant Design Pro V5 从服务器请求菜单(typescript版)第5张

【开始改造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 文件中

Ant Design Pro V5 从服务器请求菜单(typescript版)第6张

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

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

1. 调整接口

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

Ant Design Pro V5 从服务器请求菜单(typescript版)第7张

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

Ant Design Pro V5 从服务器请求菜单(typescript版)第8张

3. 调整组件menuDataRender为使用传进来的菜单数据(以前那个方法不用了)

Ant Design Pro V5 从服务器请求菜单(typescript版)第9张

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

Ant Design Pro V5 从服务器请求菜单(typescript版)第10张

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

Ant Design Pro V5 从服务器请求菜单(typescript版)第11张

【运行一下试试效果】

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

cnpm start

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

Ant Design Pro V5 从服务器请求菜单(typescript版)第12张

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

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

免责声明:文章转载自《Ant Design Pro V5 从服务器请求菜单(typescript版)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Fiddler实现手机抓包——小白入门u盘启动盘安装centos7.5操作系统下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

java连接数据库时的报错

//java连接数据库时的报错1 package Java数据库编程; 2 3 import java.sql.DriverManager; 4 import java.sql.SQLException; 5 6 import com.mysql.jdbc.Connection; 7 8 public class ConnectionD...

高性能 Windows Socket 组件 HPSocket

高性能 Windows Socket 组件 HP-Socket v2.1.1 正式发布(源代码及测试用例下载) HP-Socket   以前为某大型通信项目开发了一套通用 Windows Socket TCP 底层通信组件,组件代号为 HP-Socket。现在把 HP-Socket 的所有代码向大众公开,希望能对大家有所帮助;另外,为了让大家能更方便的学...

Java—RequestMapping相关用法

RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。它有6个属性:1.value:指定请求的具体地址:value的uri值为以下三类:A) 可以指定为普通的具体值:(value = "/add"),其直接访问controller的路径是ip:port/member/a...

Servlet第四篇【request对象常用方法、应用】

什么是HttpServletRequest HttpServletRequest**对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,**HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。 简单来说,要得到浏览器信息,就找HttpServletRequest对象 HttpServletRequest...

从js向Action传中文参数出现乱码问题的解决方法

Action获取jsp表单中的中文参数,只要整个项目都采用UTF-8编码格式都不会出现乱码问题;但JSP中用到JS,并从JS向Action传中文参数,就会出现中文乱的现象     做项目的时候,发现Action获取jsp表单中的中文参数,只要整个项目都采用UTF-8编码格式都不会出现乱码问题;但JSP中用到JS,并从JS向Action传中文参数,就会出现中...

1.golang数据类型,转换,变量类型检查,生命周期、闭包,打印方法,指针简介

golang是强类型,静态语言 1.golang 数据类型 布尔类型 true/false var b bool ,在golang底层bool不是1/0表示的 数值类型 :var i int =3 / var i:=3 数字在计算机内部是以二进制的方式存储的,二进制位就是一系列布尔值,取值要么为1,要么为0. 1位表示1或0,对于4位整数可以表示16个不同...