ant desgin prov5关于服务端请求菜单
官方文档地址点击此处
官方是这么说的:
如果你的数据希望通过 initialState 来保存,你可以在 request 中直接读取,这样每次 initialState 变化都会重新加载菜单
// https://umijs.org/zh-CN/plugins/plugin-layout
export const layout: RunTimeLayoutConfig = ({ initialState }) => {
return {
menu: {
// 每当 initialState?.currentUser?.userid 发生修改时重新执行 request
params: initialState,
request: async (params, defaultMenuData) => {
return initialState.menuData;
},
},
};
};
一定要看文档这个不要看文档上面那个
上面那个代码如下:
request: async (params, defaultMenuData) => {
// initialState.currentUser 中包含了所有用户信息
const menuData = await fetchMenuData();
return menuData;
},
上面这个是有坑的,如果按上面的这种写法,写了后当你页面刷新,注意是刷新不是切换路由,当你刷新页面的时候,菜单直接就没了
所以我的解决方式如下
import { PageLoading } from '@ant-design/pro-layout';
import { history, Link } from 'umi';
import RightContent from '@/components/RightContent';
import Footer from '@/components/Footer';
import { currentUser as queryCurrentUser } from './services/ant-design-pro/api';
import { BookOutlined, LinkOutlined } from '@ant-design/icons';
import defaultSettings from '../config/defaultSettings';
import routersConfigUser from '../config/routersConfigUser';
import * as indexApi from '@/services/ant-design-pro/api';
const isDev = process.env.NODE_ENV === 'development';
const loginPath = '/user/login';
/** 获取用户信息比较慢的时候会展示一个 loading */
export const initialStateConfig = {
loading: <PageLoading />,
};
/**
* @see https://umijs.org/zh-CN/plugins/plugin-initial-state
* */
export async function getInitialState() {
const fetchUserInfo = async () => {
try { // 用户详情获取注释掉
const msg = await queryCurrentUser();
return msg.data;
return { name: 'Serati Ma' }
} catch (error) {
history.push(loginPath);
}
return undefined;
}; // 如果是登录页面,不执行
// 服务端获取路由数据并处理的方法
const fetchMenuData = async () => {
try {
const res = await indexApi.menuNav(); // 获取路由接口
let tempMap = {}
res.data.list.forEach((item) => {
let sbr = null
if (item) {
if (item.list && item.list.length > 0) {
item.list.forEach((node) => {
sbr = node.url.split('/')
tempMap[node.url] = node
})
}
if (sbr) {
tempMap[`/${sbr[1]}`] = item
}
}
})
// routersConfigUser这个是我在config里面的routers文件复制出来一个文件和routers内容一样,只是加了几个一级路由和二级路由
routersConfigUser.forEach((item) => {
if (tempMap[item.path]) {
item.hideInMenu = false
if (item.routes && item.routes.length > 0) {
item.routes.forEach((node) => {
if (tempMap[node.path]) {
node.hideInMenu = false
} else {
node.hideInMenu = true
}
})
}
}
})
return routersConfigUser;
} catch (error) {
history.push('/user/login'); // 这个就是用来控制你页面刷新后,路由会不会重新加载的
}
return undefined;
};
if (history.location.pathname !== loginPath) {
const currentUser = await fetchUserInfo();
const menuData = await fetchMenuData();
return {
fetchUserInfo,
currentUser,
settings: defaultSettings,
menuData,
};
}
return {
fetchUserInfo,
settings: {},
// menuData: []
};
} // ProLayout 支持的api https://procomponents.ant.design/components/layout
export const layout = ({ initialState }) => {
return {
menu: { // 路由服务端获取,必须用这个属性不然的话第一次登陆进去后页面是没有路由的,只有刷新后才有,下面的params和request也是必须的
// 每当 initialState?.currentUser?.userid 发生修改时重新执行 request
params: {
userId: initialState?.currentUser?.userId,
},
request: () => initialState.menuData,
},
rightContentRender: () => <RightContent />,
disableContentMargin: false,
// waterMarkProps: { // 水印背景
// content: initialState?.currentUser?.name,
// },
footerRender: () => <Footer />,
onPageChange: () => {
const { location } = history; // 如果没有登录,重定向到 login
if (!initialState?.currentUser && location.pathname !== loginPath) {
history.push(loginPath);
}
},
// links: isDev
// ? [
// <Link to="/umi/plugin/openapi" target="_blank">
// <LinkOutlined />
// <span>OpenAPI 文档</span>
// </Link>,
// <Link to="/~docs">
// <BookOutlined />
// <span>业务组件文档</span>
// </Link>,
// ]
// : [],
menuHeaderRender: undefined,
// 自定义 403 页面
// unAccessible: <div>unAccessible</div>,
...initialState?.settings,
};
};
export const dva = {
config: {
onError(e) {
e.preventDefault();
console.error(e.message);
},
},
};
具体的请求servers里面的就不用放了,用这个框架一般都会的,问题解决,如有补充请留言