参考官网 路由和菜单

antd pro中默认菜单根据路由配置,匹配登录用户的权限进行生成。
路由节点需要配置authority属性来辅助生成菜单,如:

{
	path: '/admin',
    name: 'admin',
    icon: 'crown',
    component: './Admin',
    authority: ['admin'],
},

考虑到需要比较灵活的配置权限角色,避免增加或修改角色权限后需要更改前端,
所以通过后端返回各用户的菜单。

路由中不写死权限的话,假如用户没有admin权限,使用/admin也可以访问到不在菜单中的页面,但获取业务数据等请求本身后端也会校验权限返回错误,前端处理异常后会跳转到403页面,不知道是不是有更好的方法。

从服务器请求菜单,官网中是这么说明的:

你可以在 src/layouts/BasicLayout.tsx 中修改 menuDataRender,并在代码中发起 http 请求,只需服务器返回下面格式的 json 即可
注意: path 必须要在 config.ts 中定义。(约定式路由不需要,只需页面真实有效即可)
注意: 如果没有选用 typescript,config.js 中菜单的嵌套写法,需要把 “children” 换成 “routes”

[
  {
    "path": "/dashboard",
    "name": "dashboard",
    "icon": "dashboard",
    "children": [
      {
        "path": "/dashboard/analysis",
        "name": "analysis"
      },
      {
        "path": "/dashboard/monitor",
        "name": "monitor"
      },
      {
        "path": "/dashboard/workplace",
        "name": "workplace"
      }
    ]
  }
  // ....
]

冲冲冲…
先写个mock方便测试~~mock/menu.js:

export default {
  'GET /api/currentMenu': [
    {
      path: '/welcome',
      name: 'welcome',
      icon: 'smile',
    },
    {
      path: '/admin',
      name: 'admin',
      icon: 'crown',
    },
    {
      path: '/list',
      name: 'list.table-list',
      icon: 'table',
    },
  ],
}

继续写个model来发起请求和变更state~~models/userMenu.js:

import {queryCurrentMenu} from "@/services/user";

const UserMenuModel = {
  namespace: 'userMenu',
  state: {
    currentMenu: [],
  },
  effects: {
    //代表事件的Action对象,由于函数体不需要Action内容,所有使用`_`占位符代替Action对象了
    //const { call, put } = sagaEffects
    //也可以yield call(request, url), 这里统一放到services
    *fetchCurrentMenu(_, { call, put }) {
      const response = yield call(queryCurrentMenu);
      yield put({
        type: 'saveCurrentMenu',
        payload: response,
      });
    },
  },
  reducers: {
    saveCurrentMenu(state, action) {
      return { ...state, currentMenu: action.payload || [] };
    },
  },
}
export default UserMenuModel;

在service加点代码~~services/user.js:

export async function queryCurrentMenu() {
  return request('/api/currentMenu');
}

接下来就是调整下BasicLayout了:

调整一下connect 的mapStateToProps, 使从model中注入props

export default connect(({ global, settings, userMenu }) => ({
  collapsed: global.collapsed,
  settings,
  menuData: userMenu.currentMenu,
}))(BasicLayout);

用useEffect发送Action,因为BasicLayout是属于函数组件非类组件,没有生命周期函数如componentDidMount()等;
从props取出menuData;
变更menuDataRender;
实现如下:

const BasicLayout = props => {
  const {
    ...
    menuData,
  } = props;
  /**
   * constructor
   */
  useEffect(() => {
    if (dispatch) {
      dispatch({
        type: 'userMenu/fetchCurrentMenu',
      });
    }
  }, []);
  ...
  render(
  	...
  	menuDataRender={() => menuData}
  	...
  )
};

运行瞅瞅
菜单正常显示了,图标没显示出来!
Console这样提示

为了兼容 antd@4,我们会在下个版本删除配置 icon: string 生成icon的用法。请查看
https://pro.ant.design/blog/antd-4.0-cn 寻找解决方式!

查看后是这么说的:

但是 Pro 中支持通过设置 icon 配置菜单图标,在 4.0 中将无法得到支持,所以我们提供了相应的插件来保留此功能。
使用方式如下 :
yarn add umi-plugin-antd-icon-config -D
并且在 config.ts 中设置

export default {
  plugins: [['umi-plugin-antd-icon-config', {}]],
};

我使用的是npm,相当于

npm install umi-plugin-antd-icon-config --save-dev

添加依赖会更新 package.json
–dev 依赖会记录在 package.json 的 devDependencies 下

然后,,图标还是没出来。。
怀疑是不是环境问题,依赖的包版本哪里不对可能。先这样吧。