1.打开src/app.jsx,我们之前在app.jsx中做了用户信息的全局初始化,即在getInitialState方法中调用后台接口获取用户数据,并return出去,getInitialState()方法返回的数据最后会被默认注入到一个 namespace 为 @@initialState 的 model 中。可以通过 useModel 这个 hook 来消费它,我们把全局初始数据章节中用来消费getInitialState()方法中返回的数据示例代码再过一下,加深理解

    1. import React from 'react';
    2. import { useModel } from 'umi';
    3. import { Spin } from 'antd';
    4. export default () => {
    5. const { initialState, loading, refresh, setInitialState } = useModel('@@initialState');
    6. if (loading) {
    7. return <Spin />;
    8. }
    9. return <div>{initialState.userName}</div>;
    10. };

    在任何组件中我们可以用useModel(‘@@initialState’)拿getInitialState()中return的数据,
    上面的示例取出了initialState.userName

    1. const { initialState, loading, refresh, setInitialState } = useModel('@@initialState');

    2.菜单数据的处理跟用户信息的处理类似,我们先导入service文件中的getCurrentUserMenus方法

    1. import { getCurrentUserMenus } from './services/ant-design-pro/menu';

    3.在getInitialState() 中fetchUserInfo函数后面,定义获取菜单数据的函数fetchUserMenus,代码如下

    1. const fetchUserMenus = async () => {
    2. try {
    3. const menuData = await getCurrentUserMenus();
    4. return menuData;
    5. } catch (error) {
    6. history.push(loginPath);
    7. }
    8. return undefined;
    9. };

    fetchUserMenus就是调用getCurrentUserMenus()拿到转换好的菜单数据,并return 出去。

    4.跟fetchUserInfo一样,把fetchUserMenus一样return 出去,必须是登录成功获取到token以后,才能获取菜单信息,增加一个本地token的判断,修改完毕后,完整的getInitialState代码如下

    1. export async function getInitialState() {
    2. const fetchUserInfo = async () => {
    3. try {
    4. const msg = await queryCurrentUser();
    5. return msg.user;
    6. } catch (error) {
    7. history.push(loginPath);
    8. }
    9. return undefined;
    10. };
    11. const fetchUserMenus = async () => {
    12. try {
    13. const menuData = await getCurrentUserMenus();
    14. return menuData;
    15. } catch (error) {
    16. history.push(loginPath);
    17. }
    18. return undefined;
    19. };
    20. if (history.location.pathname !== loginPath) {
    21. const token = localStorage.getItem('access_token');
    22. if (!token) {
    23. history.push(loginPath);
    24. return {
    25. fetchUserInfo,
    26. fetchUserMenus,
    27. menuData: [],
    28. settings: {},
    29. };
    30. }
    31. const currentUser = await fetchUserInfo();
    32. const menuData = await fetchUserMenus();
    33. return {
    34. fetchUserInfo,
    35. fetchUserMenus,
    36. currentUser,
    37. menuData,
    38. settings: {},
    39. };
    40. }
    41. return {
    42. fetchUserInfo,
    43. fetchUserMenus,
    44. menuData: [],
    45. settings: {},
    46. };
    47. }

    5.然后在src/app.jsx中的layout中我们就可以直接使用menuData的数据

    1. export const layout = ({ initialState }) => {
    2. ...initialState?.settings,
    3. }

    在…initialState?.settings,前加一行代码,
    menuDataRender: () =>{ return initialState?.menuData },登录以后,就可以看到菜单数据了

    1. export const layout = ({ initialState }) => {
    2. menuDataRender: () =>{
    3. return initialState?.menuData
    4. },
    5. ...initialState?.settings,
    6. }

    6.登录后,原来的config/config.js中的菜单不会出现了,数据库中的菜单树会展现出来,如下图所示:
    image.png

    7.这里有个菜单的图标问题,我们拿到的菜单图标显示的都是字符串,没有正常显示图标,这里我们在下一节进行完善