类似的问题:#4286
除了控制权限外,还有办法吗?
js 在浏览器端是不能操作文件的。
权限的判断应该主要在后台做,前端负责显示隐藏即可
我通过在BasicLayout中 动态修改props.route.routes实现了。
大致步骤:
能给出一个示例代码吗?我按照你的做法不行哎。router.push(window.location.pathname);这一步是干嘛的?
const BasicLayout: React.FC<BasicLayoutProps> = props => {
const { dispatch, children, settings, route, menuData } = props;
const [components, setComponents] = useState<Map<string, any>>();
function addRoute(menuItem: MenuDataItem) {
if (menuItem.children && menuItem.children.length > 0) {
menuItem.children.forEach(t => addRoute(t));
} else if (route && route.routes && components) {
route.routes.unshift({
path: menuItem.path,
component: components.get(menuItem.dataType),
exact: true,
});
}
}
useEffect(() => {
if (route && route.routes && components && menuData) {
menuData.forEach(addRoute);
router.push(window.location.pathname);
}
}, [components, menuData]);
useState(() => {
if (dispatch) {
dispatch({
type: 'user/fetchCurrent',
});
dispatch({
type: 'settings/getSetting',
});
dispatch({
type: 'menu/getMenuData',
});
}
if (route && route.routes) {
const map = new Map<string, any>();
route.routes.filter(t => t.name).forEach(t => map.set(t.name!, t.component));
setComponents(map);
}
});
menuData是一个MenuDataItem[],在models中加载的
dataType 是服务端返回的 用于从 components 中获取组件的
components 里面的东西是一开始router.config里面写好的


@LiYanGang
const BasicLayout: React.FC<BasicLayoutProps> = props => { const { dispatch, children, settings, route, menuData } = props; const [components, setComponents] = useState<Map<string, any>>(); function addRoute(menuItem: MenuDataItem) { if (menuItem.children && menuItem.children.length > 0) { menuItem.children.forEach(t => addRoute(t)); } else if (route && route.routes && components) { route.routes.unshift({ path: menuItem.path, component: components.get(menuItem.dataType), exact: true, }); } } useEffect(() => { if (route && route.routes && components && menuData) { menuData.forEach(addRoute); router.push(window.location.pathname); } }, [components, menuData]); useState(() => { if (dispatch) { dispatch({ type: 'user/fetchCurrent', }); dispatch({ type: 'settings/getSetting', }); dispatch({ type: 'menu/getMenuData', }); } if (route && route.routes) { const map = new Map<string, any>(); route.routes.filter(t => t.name).forEach(t => map.set(t.name!, t.component)); setComponents(map); } });menuData是一个MenuDataItem[],在models中加载的
dataType 是服务端返回的 用于从 _components_ 中获取组件的
_components_ 里面的东西是一开始router.config里面写好的
@LiYanGang
大佬,BasicLayout组件中的 router.push(window.location.pathname);这个方法的router没有定义吧?
@LiYanGang
import { router } from 'umi';
@liangyongrui


useEffects这里的menudata怎么获取不到数据呢?
@mushroomlb 是不是最下面的connect没有传递数据?或者传递的格式有问题?
const BasicLayout: React.FC<BasicLayoutProps> = props => { const { dispatch, children, settings, route, menuData } = props; const [components, setComponents] = useState<Map<string, any>>(); function addRoute(menuItem: MenuDataItem) { if (menuItem.children && menuItem.children.length > 0) { menuItem.children.forEach(t => addRoute(t)); } else if (route && route.routes && components) { route.routes.unshift({ path: menuItem.path, component: components.get(menuItem.dataType), exact: true, }); } } useEffect(() => { if (route && route.routes && components && menuData) { menuData.forEach(addRoute); router.push(window.location.pathname); } }, [components, menuData]); useState(() => { if (dispatch) { dispatch({ type: 'user/fetchCurrent', }); dispatch({ type: 'settings/getSetting', }); dispatch({ type: 'menu/getMenuData', }); } if (route && route.routes) { const map = new Map<string, any>(); route.routes.filter(t => t.name).forEach(t => map.set(t.name!, t.component)); setComponents(map); } });menuData是一个MenuDataItem[],在models中加载的
dataType 是服务端返回的 用于从 _components_ 中获取组件的
_components_ 里面的东西是一开始router.config里面写好的
@LiYanGang
您好,问下:1. component: components.get(menuItem.dataType),从服务器传回来的dataType具体是什么?大佬能否给个示例看下,我按照你的方法动态渲染了菜单,但是点击菜单后没有加载出来页面,服务器返回的菜单path和config.ts中写的一样,现在不知道错误在哪里了。connect是这样写的

这个地方改成这样后,报错了,不影响使用,但是总觉得不好看,有没有解决办法,吾乃前端小白,大佬能否指点一二,感谢!@dong-gy
import { MenuDataItem } from '@ant-design/pro-layout';
menuData 的类型 MenuDataItem[]
dataType 是服务端 返回的, 叫什么名字都可以, 只要能和路由 的配置文件对上即可
确实可以了,感谢 @liangyongrui
这是动态菜单,不是动态路由。
他在BasicLayout文件里直接修改了route树 ,即使左侧菜单里没有的组件也可以在这里附上权限设置,修改的范围是basiclayout下面的所有子组件@DWAO

类似这个方法。是先初始化所有的组件,在basicLayout下unshift新的路由,新的路由虽然和开始config.route里同名,但是unshift会先匹配到,这里就可以做很多事情了
const BasicLayout: React.FC<BasicLayoutProps> = props => { const { dispatch, children, settings, route, menuData } = props; const [components, setComponents] = useState<Map<string, any>>(); function addRoute(menuItem: MenuDataItem) { if (menuItem.children && menuItem.children.length > 0) { menuItem.children.forEach(t => addRoute(t)); } else if (route && route.routes && components) { route.routes.unshift({ path: menuItem.path, component: components.get(menuItem.dataType), exact: true, }); } } useEffect(() => { if (route && route.routes && components && menuData) { menuData.forEach(addRoute); router.push(window.location.pathname); } }, [components, menuData]); useState(() => { if (dispatch) { dispatch({ type: 'user/fetchCurrent', }); dispatch({ type: 'settings/getSetting', }); dispatch({ type: 'menu/getMenuData', }); } if (route && route.routes) { const map = new Map<string, any>(); route.routes.filter(t => t.name).forEach(t => map.set(t.name!, t.component)); setComponents(map); } });menuData是一个MenuDataItem[],在models中加载的
dataType 是服务端返回的 用于从 _components_ 中获取组件的
_components_ 里面的东西是一开始router.config里面写好的
@LiYanGang
其实有个bug就是二级菜单下routes和子集下的routes获取不到呢
类似的问题:#4286
除了控制权限外,还有办法吗?
在src目录下面,新建一个app.js,就可以获取到config routes了,然后对它进行修改就好。
import pathRegexp from "path-to-regexp";
let extraRoutes;
const updateRouteAuthority = (path, routeData, sAuth) => {
if (routeData && Array.isArray(routeData)) {
routeData.forEach(route => {
if (route.path) {
if ((route.path === '/') || (pathRegexp(${route.path}/(.*)).test(${path}/))) {
if (route.path === path && sAuth) {
route.authority = sAuth;
}
if (route.routes) {
updateRouteAuthority(path, route.routes, sAuth);
}
}
}
});
}
};
const patchEachRoute = (serverRoute, routes) => {
if (serverRoute && Array.isArray(serverRoute)) {
serverRoute.forEach(eRoute => {
updateRouteAuthority(${eRoute.path}, routes, eRoute.authority);
if (eRoute.children) {
patchEachRoute(eRoute.children, routes)
}
});
}
};
export function patchRoutes({routes}) {
// console.log("routes",routes,extraRoutes)
if (extraRoutes) {
patchEachRoute(extraRoutes, routes);
}
}
export function render(oldRender) {
fetch('/api/menu', { method: 'GET' }) //mock的
.then(res => res.json())
.then(res => {
extraRoutes = res;
oldRender();
})
}
Most helpful comment
我通过在BasicLayout中 动态修改props.route.routes实现了。
大致步骤: