antd pro 后台获取菜单渲染

315 阅读3分钟

由于公司一直在用vue的框架,但是作为一个思进取的咸鱼怎么可能安于现状呢?于是乎萌生二次开发antdpro的想法

首先git拉取框架

安装依赖

运行 完美!!

紧接着搞成适用于自己公司的框架,重新引入request 调用接口

似乎一切都那么顺利的时候,我发现菜单居然渲染不进来!!!

在苦恼了很久之后又因为突然有工作插进来 导致该项目停滞了 ,最近突然又不那么忙了,于是乎继续之前的工作

在查阅各种文档之后,实现如下:

主要修改文件: app.tsx

后台返回菜单渲染主要是这里的代码

image.png

话不多说 ,直接上流程

首先在app.tsx 文件中 修改 getInitialState 函数 代码如下

export async function getInitialState(): Promise<{
  settings?: Partial<LayoutSettings>;
  currentUser?: API.CurrentUser;   // 用于存储用户信息 API.CurrentUser 是ts语法 声明的改对象类型
  fetchUserInfo?: () => Promise<API.CurrentUser | undefined>; // 获取用户信息接口
  fetchUserMenu?:() => Promise<API.CurrentUser | undefined>;  // 获取菜单接口
  menuData?: API.routerType[]       // 存储菜单
}> {
  const fetchUserInfo = async () => {
    try {
      const msg = await getUserInfo();
      return msg.result;
    } catch (error) {
      history.push(loginPath);
    }
    return undefined;
  };
  const fetchUserMenu = async ()=> {
    try {
      const msg = await getUserMenu();
      return msg.result;
    } catch (error) {
      history.push(loginPath);
    }
    return [];

  }
  var currentUser
  var menuData:API.routerType[] = []
  const USER_TOKEN = localStorage.getItem('userToken')
  // 当用户登录且点击浏览器刷新时触发
  if(USER_TOKEN){
    currentUser = await fetchUserInfo();
    // 这部分是我自己处理菜单格式的代码  
    let menu = await fetchUserMenu()
    let m = merge([menu])  // 个人处理菜单的方法 这里就不贴了
    if(m.length)
    menuData = m[0].routes || []
  }
  // 当用户登录且浏览器地址为登录页地址时触发  其中 loginPath 是我的登录页地址 请自行修改
  // 防止用户手动输入登录页地址
  if(history.location.pathname !== loginPath){
    if(currentUser)history.push(history.location.pathname);
    else history.push(loginPath);
  }
  return {
    fetchUserInfo,
    fetchUserMenu,
    currentUser,
    menuData,
    settings: {},
  };
}

上边代码是需要自己改些东西才能用的!!!

这部分代码我自己理解是在刷新浏览器时会触发,具体用处请自行去官网查看😌😌

紧接着修改当前文件的 RunTimeLayoutConfig 方法

这个方法是在页面发生改变时触发

代码如下:

export const layout: RunTimeLayoutConfig = ({ initialState }) => {
  return {
    rightContentRender: () => <RightContent />,
    disableContentMargin: false,
    waterMarkProps: {
      content: initialState?.currentUser?.name,
    },
    onPageChange: () => {
      const { location } = history;
      // 如果没有登录,重定向到 login
      if (!initialState?.currentUser && location.pathname !== loginPath) {
        history.push(loginPath);
      }else if(initialState?.currentUser && location.pathname === loginPath){
        history.push('/');
      }
    },
    menuHeaderRender: undefined,
    // 自定义 403 页面
    // unAccessible: <div>unAccessible</div>,
    ...initialState?.settings,
    // 主要是这部分  将后端返回的菜单放进去
    menuDataRender:()=>{
        let serverMenu:API.routerType[] = []
        if(initialState?.menuData?.length){
          serverMenu = initialState?.menuData || []
        }
        return [...serverMenu]
      },
  };
};

如果只是这样的话需要刷新页面菜单才会渲染出来,所以我们在登录页获取菜单,然后放在 menuData 中

登录页代码如下

 const handleSubmit = async (values: API.LoginParams) => {
    try {
      // 登录
      const msg = await login({ ...values });
      if (msg.success) {
        const defaultLoginSuccessMessage = intl.formatMessage({
          id: 'pages.login.success',
          defaultMessage: '登录成功!',
        });
        const menu = await fetchUserMenu();  // 获取菜单
        const res = await fetchUserInfo();   // 获取用户信息
        let m = merge([menu.result])         // 处理菜单数据
        let menuData:API.routerType[] = []
        if(m.length) menuData = m[0].routes || []
        if(res.success){
          setInitialState((s) => ({ ...s, currentUser: res.result,menuData})); // 主要是这里呦~  把菜单数据放在initState里
          message.success(defaultLoginSuccessMessage);
          history.replace('/')
          return
        }
      }
      // 如果失败去设置用户错误信息
      setUserLoginState(msg.message);
    } catch (error) {
      const defaultLoginFailureMessage = intl.formatMessage({
        id: 'pages.login.failure',
        defaultMessage: '登录失败,请重试!',
      });
      message.error(defaultLoginFailureMessage);
    }
};

完美 搞定!!

效果如下 刷新页面也没问题

2022-10-19 17-08-28.2022-10-19 17_10_24的副本.gif

============

tip: 路由关系一定要自己配好,不然都是404!!

=============

纯用于记录自己的学习路程,当然如果能帮到你,我也是很开心的😄

最后,欢迎大佬们来指正问题~~~😘😘😘