ant-design / ant-design-pro

👨🏻‍💻👩🏻‍💻 Use Ant Design like a Pro!
https://pro.ant.design
MIT License
36.4k stars 8.14k forks source link

请问如何实现动态路由 #9462

Closed resuper closed 2 years ago

resuper commented 2 years ago

🧐 需求:菜单从数据库加载,路由也从数据库加载。

前言万语其实都在下面这张图和下面的示例代码中。。

image

💻 示例代码

route.js

import staticRoutesHighPriority from './staticRoutesHighPriority';
import staticRoutesLowPriority from './staticRoutesLowPriority';
export default [...staticRoutesHighPriority, ...staticRoutesLowPriority];

staticRoutesHighPriority.js

export default [
  {
    path: '/',
    redirect: '/welcome',
  },
];

staticRoutesLowPriority.js

/**
 * component 的值如果是相对路径,会以 src/pages 为基础路径开始解析
 * 官方参考:https://pro.ant.design/zh-CN/config/config#routes
 */
export default [
  {
    path: '/user',
    layout: false,
    routes: [
      {
        path: '/user',
        routes: [
          {
            name: 'login',
            path: '/user/login',
            component: './user/Login',
          },
        ],
      },
      {
        component: './404',
      },
    ],
  },
  {
    path: '/developer',
    name: '开发者',
    title: '开发者',
    icon: 'crown',
    component: './example',
  },
  {
    path: '/welcome',
    name: 'welcome',
    icon: 'smile',
    component: './Welcome',
  },
  {
    component: './404',
  },
];

运行时配置,只贴出了实现动态加载菜单的部分 app.jsx

export const layout = ({ initialState }) => {
  return {
    // 其他配置省略...
    menu: {
      // 每当 initialState?.currentUser?.userid 发生修改时重新执行 request
      params: {
        userId: initialState,
      },
      request: async (params, defaultMenuData) => {
        // 图标映射
        initialState.MenuInfo.forEach((item) => {
          item.icon = iconMapping[item.icon];
        });
        return initialState.MenuInfo;
      },
    },
    ...initialState?.settings,
  };
};

// 模拟动态路由 ,换了n种写法依然不好使
let extraRoutes = [];
// 修改路由
export function patchRoutes({ routes }) {
  debugger;
  console.log(routes);
  const comp = require(`/src/pages/Welcome`);
  const comp2 = ()=> import('/src/pages/Welcome');
  console.log(comp);
  routes[1].routes.unshift({
    path: '/foo',
    exact: false,
    // component: require(`@/pages/example/NewPage`).default,
    // component: require(`@/pages/Welcome`).default,
    // component: ()=> import('/src/pages/Welcome'),
    component: ()=> import('/src/pages/Welcome').then((res)=>{
      console.log(res)
    }),
  });
}

export function render(oldRender) {
  oldRender();
}
caimingyi484 commented 2 years ago

同问 app.jsx文件

import { dynamic } from '@umijs/runtime';
import LoadingComponent from '@ant-design/pro-layout/es/PageLoading';
let extraRoutes = [];
export function patchRoutes({ routes }) {
  routes[1].routes = routes[1].routes.concat(extraRoutes);
  // 如果最后页面是404,所以要插入到时候第二个
  // routes[1].routes.splice(-1, 0, ...extraRoutes);
  console.log(history.location.pathname, routes)
  console.log(extraRoutes)
}
export function render(oldRender) {
  // fetch('/api/routes').then(res=>res.json()).then((res) => {
      extraRoutes = [{
        path: '/welcome2',
        name: 'welcome',
        icon: 'smile',
        // hideInMenu: true,
        exact: true,
        access: "canAdmin",
        component: dynamic({ loader: () => import('./pages/Form'), loading: LoadingComponent}),
      }];
      oldRender();
  // })
}

终于解决了!!!!!!

chenshuai2144 commented 2 years ago

不推荐使用动态路由,动态菜单效果更好

ldwonday commented 2 years ago

@chenshuai2144 patchRoutes和childrenRender不兼容,用了patchRoutes后childrenRender不执行了

xiahller commented 2 years ago

不推荐使用动态路由,动态菜单效果更好

请问后续会支持吗,我遇到了同样的问题~

chenshuai2144 commented 2 years ago

不会支持的,不要玩这种花样

xXAvoraXx commented 1 year ago

@chenshuai2144 为什么不推荐动态路由?