Ant-design-pro: 分享一下V2版本的服务器端获取菜单数据

Created on 15 Dec 2018  ·  16Comments  ·  Source: ant-design/ant-design-pro

第一步:services/api.js

export async function getMenu() {
  return request('/api/*********/GetMenu', {
    method: 'POST'
  });
}

第二步:models/menu.js

引入
import { getMenu } from '@/services/api';

effects: {
    *getMenuData({ payload }, {call, put }) {
      const response = yield call(getMenu);//这里调用接口
      // const { routes, authority } = payload; //这里是原代码
      const menuData = filterMenuData(memoizeOneFormatter(response.data.routes, response.data.authority));
      const breadcrumbNameMap = memoizeOneGetBreadcrumbNameMap(menuData);
      yield put({
        type: 'save',
        payload: { menuData, breadcrumbNameMap },
      });
    },
  },

第三步:在服务器端严格按照config/router.config.js中的json格式返回数据,注意属性名大小写,值类型等。

注:个人建议角色不要在客户端Local Storage中,因为ant design pro运行在前端,怕被篡改角色,即使不会暴露敏感功能,如果使用了JWT,应该把安全性和角色问题放到服务端处理。小弟最近才上手ant不知道理解得对不对,只是把这几天的研究成果放到这来希望对入门的新手有用。望各位大神指点。

👨🏼‍🌾 FAQ

All 16 comments

为啥子,我感觉v1版本的菜单更好理解,后端返回还更好控制。v2的还是看的有的多参

先格式化一下文章?

v1版本之前models在router文件中可以挂载,v2是 在 umi 中 models 文件夹中的 dva model 会被自动挂载,要按照他文件下的格式嘛

@LKCheng 我研究完写的这个代码只能获取服务端menu,因为自动挂载了router.config.js,角色也在其中,导致后面添加了新页面时访问跳转到403。还需要处理一下Authorized。

@lattemj 对于第三步中的数据,我在mock中写了假数据、数据是copy的router.config.js中的数据。但是菜单显示不出来、这边有没有现成的json格式么。

@jinhai123 router.config.js中的数据不能全用,你要知道哪一部份才是菜单的路由设置,你也可以查看源码解析的哪一部份:
```
{
path: '/dashboard',
name: 'dashboard',
icon: 'dashboard',
routes: [
{
path: '/dashboard/analysis',
name: 'analysis',
component: './Dashboard/Analysis',
},
{
path: '/dashboard/monitor',
name: 'monitor',
component: './Dashboard/Monitor',
},
{
path: '/dashboard/workplace',
name: 'workplace',
component: './Dashboard/Workplace',
},
],
},

BasicLayout.js 修改部分

  render() {
    const {
      navTheme,
      layout: PropsLayout,
      children,
      location: { pathname },
      isMobile,
      menuData,
      breadcrumbNameMap,
      route: { routes },
      fixedHeader,
    } = this.props;

    const isTop = PropsLayout === 'topmenu';
    const routerConfig = this.getRouterAuthority(pathname, routes);
   //改成
const routerConfig = this.getDymincRouterAuthority(pathname, routes);

权限判断方法修改

  getRouterAuthority = (pathname, routeData) => {
    let routeAuthority = ['noAuthority'];
    const getAuthority = (key, routes) => {
      routes.map(route => {
        if (route.path && pathToRegexp(route.path).test(key)) {
          routeAuthority = route.authority;
        } else if (route.routes) {
          routeAuthority = getAuthority(key, route.routes);
        }
        return route;
      });
      return routeAuthority;
    };
    return getAuthority(pathname, routeData);
  };
  /**动态菜单权限判断**/
  getDymincRouterAuthority = (pathname, routeData) => {
    let routeAuthority = ['noAuthority'];
    const getAuthority = (key, routes) => {
      routes.map(route => {
        if (route.path && pathToRegexp(route.path).test(key)) {
          routeAuthority = route.authority;
        } else if (route.children) {
          routeAuthority = getAuthority(key, route.children);
        }
        return route;
      });
      return routeAuthority;
    };
    return getAuthority(pathname, routeData);
  };

动态路由数据

{
    path: '/goods',
    name: 'goods',
    icon: 'shop',
    authority: ['admin', 'user'],
    routes: [
      {
        path: '/goods/success',
        name: 'create',
        component: './Goods/Success',
      },
      { path: '/goods/list', name: 'list', component: './Goods/Error' },
      { path: '/goods/category', name: 'category', component: './Goods/Category' },
      { path: '/goods/fail', name: 'edit', component: './Goods/Fail' },
    ]
  },

@lattemj 我也是你这种方案实现的,但是新增页面一直报这个错误
image

@denghp path和component需要在router.config.js中全部配置好,具体的菜单分级后端拼接,注意的是后端返回的页面在router.config.js中必须是存在的。这个暂时不支持动态挂载。个人理解就是假的动态菜单,控制显示而已。如果你有链接还是可以通过敲链接进,如果权限够的情况。

@denghp path和component需要在router.config.js中全部配置好,具体的菜单分级后端拼接,注意的是后端返回的页面在router.config.js中必须是存在的。这个暂时不支持动态挂载。个人理解就是假的动态菜单,控制显示而已。如果你有链接还是可以通过敲链接进,如果权限够的情况。

嗯,确实是需要在router.config.js中配置,那这样就失去了动态从服务端获取菜单的意义了,毕竟服务端是管理菜单的分级和菜单角色。

我前端时间使用vue-admin-template脚手架实现动态获取菜单是思路:
1、服务端获取菜单及对应角色
2、客户端这不保存component的map

export const routerComponents = {
  Layout: {
    component: Layout
  },
  NotFound: {
    component: () => import('@/views/errorPage/404')
  },
  Dashboard: {
    component: () => import('@/views/dashboard/index')
  },
  Administrator: {
    component: () => import('@/views/auth/users/index')
  },
}

3、从服务端获取菜单递归绑定上对应的compoent

function filterConvertAsyncRouter(routes) {
  const res = []

  routes.forEach(route => {
    const tmp = { ...route }
    // 判断是否Layout
    if (route.isLayout !== undefined && route.isLayout === true) {
      tmp.component = routerComponents['Layout'].component
    } else {
      const routerComponent = routerComponents[route.name]
      if (routerComponent !== undefined) {
        tmp.component = routerComponent.component
      } else {
        tmp.component = routerComponents['NotFound'].component
      }
    }
    if (tmp.children) {
      tmp.children = filterConvertAsyncRouter(tmp.children)
    }
    res.push(tmp)
  })

  return res
}

不知道ant-design-pro能否采用这种思路实现?我看了好久也没找到router.config.js 实例化的地方

@denghp Vue支持动态router这我知道,我也做过类似的。但是这个是react的,react和angular应该都不支持动态加载路由的,这是本身机制问题,改变不了。而且人家在文档中已经给出了,不支持动态挂载router

@denghp Vue支持动态router这我知道,我也做过类似的。但是这个是react的,react和angular应该都不支持动态加载路由的,这是本身机制问题,改变不了。而且人家在文档中已经给出了,不支持动态挂载router

我是刚学react, 还是小白

@denghp Vue支持动态router这我知道,我也做过类似的。但是这个是react的,react和angular应该都不支持动态加载路由的,这是本身机制问题,改变不了。而且人家在文档中已经给出了,不支持动态挂载router

我是刚学react, 还是小白

我比你还白,,我也是这几天才知道。不知道熬了多长时间,恶补知识。前端根本一窍不通。全凭不要脸的精神一顿问。。。

@denghp Vue支持动态router这我知道,我也做过类似的。但是这个是react的,react和angular应该都不支持动态加载路由的,这是本身机制问题,改变不了。而且人家在文档中已经给出了,不支持动态挂载router

我是刚学react, 还是小白

我比你还白,,我也是这几天才知道。不知道熬了多长时间,恶补知识。前端根本一窍不通。全凭不要脸的精神一顿问。。。

互相学习,我一直做后台开发的,最近学的前端,我们的思路一致,都是通过后台JWT控制权限,前端动态加载

新手求助~请问用了上面的方式实现了动态菜单,authority准入权限怎么才能实现动态配置喃?谢谢~

新手求助请问用了上面的方式实现了动态菜单,authority准入权限怎么才能实现动态配置喃?谢谢

权限不推荐前端完全控制,用jwt好一点吧 。我也正在研究

大神们,有人做过动态菜单的国际化吗?可以和我说一下实现思路吗?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

renyi818 picture renyi818  ·  3Comments

yjz1004 picture yjz1004  ·  3Comments

952425340 picture 952425340  ·  3Comments

lvzheng0404 picture lvzheng0404  ·  3Comments

suifan picture suifan  ·  3Comments