umijs / umi

A framework in react community ✨
https://umijs.org
MIT License
15.4k stars 2.65k forks source link

配置路由,开启layout,路由配置3层,页面不渲染 #5221

Closed kisoua closed 3 years ago

kisoua commented 4 years ago

What happens?

ant-design-pro v5.0.0版本,开启layout,配置路由,在pages下面建3层目录结构,配置路由,无法跳转到最底层路由

最小可复现仓库(REQUIRED)

Provide a mini GitHub repository which can reproduce the issue. Use yarn create @umijs/umi-app then upload to your GitHub

https://codesandbox.io/s/stoic-merkle-6jjfk?file=/config/config.ts

How To Reproduce

点击access,点击role,进入role页面 , 点击click。 Steps to reproduce the behavior: 1. 2.

Expected behavior 1. 2.

Context

kisoua commented 4 years ago

@xiaohuoni

AliasT commented 4 years ago

很明显umi这种配置形式是不能嵌套子页面的。

{
  path: "/access/role",
  name: "role",
  // component: "./access/role/index",  // 删除这个。
  routes: [
    {
      path: "/access/role/detail",
      name: "detail",
      component: "./access/role/detail/index",
      menu: false
    }
  ]
}

当父级被react-router匹配到就会直接渲染,如果想要嵌套你必须自己写Route(react-router)

import Detail from './detail'

export default () => {
  return (
    <>
      <Link to="/access/role/detail">Click</Link>
      {/* 添加 */}
      <Route  path="/access/role/detail" component={Detail} />
    </>
  )
};
kisoua commented 4 years ago

那其实这个还是解决不了,你想想/access 下面有很多的子页面,/access/role下面的也有很多子页面,这种配置就不行。

另外,像页面的breadcrumb也是直接渲染父组件的breadcrumbName,就不会再往下面查找。

lmonkey-xxyd commented 4 years ago

我也遇到了同样的问题

lmonkey-xxyd commented 4 years ago

这个似乎可以解决问题。

import React from 'react';
import { history } from 'umi';
const Redirest : React.FC<{}>  = (props) => {
  const pathname = window.location.pathname;
  if(pathname == '/admin'){
      history.push('/admin/index');
  }
  return (
      <div>{ props.children }</div>
    )
}

export default Redirest;
wangyuan0108 commented 4 years ago

貌似可以通过运行时配置解决嵌套路由菜单

export const layout = {
  logout: () => {
    console.log('1234');
  }, // do something
  menuDataRender:() =>[       //此功能可以实现动态路由,用来渲染访问路由
    {
      path: '/',
      name: '路由模块1',
    },
    {
      path: '/',
      name: '路由模块2',
      children: [
        { path: '/index1', name: '路由模块2-1' },
        { path: '/user', name: '路由模块2-2' },
      ],
    },
  ],
  // rightRender: initInfo => {
  //   console.log('initInfo', initInfo);
  //   return <div>{initInfo.name}</div>;
  // }, // return string || ReactNode;
};
kisoua commented 4 years ago

@wangyuan0108 这个不是问路由菜单的问题

flowerwOw0316 commented 4 years ago

我也遇到了这个问题 我还以为是哪里写错了 想着照葫芦画瓢。。。 建立了对应的三级目录以后 访问全是404 大小写问题全检查过了。。。 一级那种就可以 二级也可以 三级gg

amin168 commented 4 years ago

看看是不是这个问题,把所有路由都要写到404前面。我试过,如果把路由写到404后面,就报404了

image

sorrycc commented 3 years ago

It's inactive above 3 months, feel free to reopen if still have problems.

SilentFlute commented 3 years ago

@sorrycc 大佬我也遇到了这个3层路由不渲染的问题:

            {
              path: '/wrongword',
              icon: 'ProfileOutlined',
              name: 'wrongword',
              routes: [
                {
                  path: '/',
                  redirect: '/wrongword/home'
                },
                {
                  name: 'home',
                  path: '/wrongword/home',
                  component: './wrongword/home/Index',
                  routes: [
                    {
                      name: 'item',
                      hideInMenu: true,
                      path: '/wrongword/home/item',
                      component: './wrongword/home/item/Index'
                    }
                  ]
                }
              ]
            }
import { history } from 'umi';
//...
history.push(`/wrongword/home/item?id=${id}`);

最里面的那一层/wrongword/home/item无法渲染, 只有name能正常显示

umi version: v3.3.4
node version: v12.16.3
win10平台
SilentFlute commented 3 years ago

@kisoua 你这个问题解决了没有呢?感觉可以把这个issue reopen一下

sorrycc commented 3 years ago

@SilentFlute 可以提个新的,给复现。

zsxing99 commented 3 years ago

遇到了同样的问题 三层路由不能用history

Echo365 commented 3 years ago

遇到了同样的问题

wohaiwo commented 3 years ago

image 当前的路由结构是 a - b -c 需要在 b 模块中 image

jingxiawl commented 3 years ago

现在这个问题解决了嘛?还是不行配置,这个感觉是很基础的功能呀。还有面包屑点击事件怎么能拿到呀

wohaiwo commented 3 years ago

现在这个问题解决了嘛?还是不行配置,这个感觉是很基础的功能呀。还有面包屑点击事件怎么能拿到呀

哪里不行 你可以在模块里面打debugger 看看有没有进去 面包屑问题 你可以 自定义 实现 itemRender 方法就行了

jingxiawl commented 3 years ago

现在这个问题解决了嘛?还是不行配置,这个感觉是很基础的功能呀。还有面包屑点击事件怎么能拿到呀

哪里不行 你可以在模块里面打debugger 看看有没有进去 面包屑问题 你可以 自定义 实现 itemRender 方法就行了

无法渲染第三层路由页面。路由跳转了,页面显示空白。也没有任何报错

wohaiwo commented 3 years ago

你可以贴一下 简单的代码 看看

jingxiawl commented 3 years ago

你可以贴一下 简单的代码 看看

export default [
  {
    path: '/boundaryandcraft',
    component: './_layout',
    name: '边界及工艺管理',
    icon: 'icon-system',
    access: 'adminRouteFilter',
    code: 'borderAndCraft',
    routes: [
      {
        path: '/boundaryandcraft/carft',
        name: '工艺工序设置',
        component: './BoundaryAndCraft/Craft',
        exact: true,
        routes: [
          {
            path: '/boundaryandcraft/carft/editbase',
            name: '工艺流程设置',
            hideInMenu: true,
            exact: true,
            component: './BoundaryAndCraft/Craft/EditBase',
          },
        ],
      },
      // {
      //   path: '/boundaryandcraft/carft/editbase',
      //   name: '工艺流程设置',
      //   hideInMenu: true,
      //   exact: true,
      //   component: './BoundaryAndCraft/Craft/EditBase',
      // },
    ],
  },
];

类似这种。第三层的页面 工艺流程设置 页面无法显示,页面空白无报错信息,按照注释的写法就可以显示 微信图片_20210830104628

wohaiwo commented 3 years ago

BoundaryAndCraft/Craft 这个模块里面有加下面这个吗 if ( ['/boundaryandcraft/carft/editbase',].includes(history.location.pathname) ) { return props.children }

jingxiawl commented 3 years ago

BoundaryAndCraft/Craft 这个模块里面有加下面这个吗 if ( ['/boundaryandcraft/carft/editbase',].includes(history.location.pathname) ) { return props.children }

没有。那这样的话一个页面好处理。下面模块多了的话不就很麻烦么?配置个路由要改两个地方

wohaiwo commented 3 years ago

BoundaryAndCraft/Craft 这个模块里面有加下面这个吗 if ( ['/boundaryandcraft/carft/editbase',].includes(history.location.pathname) ) { return props.children }

没有。那这样的话一个页面好处理。下面模块多了的话不就很麻烦么?配置个路由要改两个地方

我是这么解决的 你可以自己本地 打debugger 测试下 如果不用这个方法 欢迎提供另外的方法

jingxiawl commented 3 years ago

BoundaryAndCraft/Craft 这个模块里面有加下面这个吗 if ( ['/boundaryandcraft/carft/editbase',].includes(history.location.pathname) ) { return props.children }

没有。那这样的话一个页面好处理。下面模块多了的话不就很麻烦么?配置个路由要改两个地方

我是这么解决的 你可以自己本地 打debugger 测试下 如果不用这个方法 欢迎提供另外的方法

好的谢谢了。我也想找个更好的方法来解决这个问题

wohaiwo commented 3 years ago

欢迎回来二次交流

------------------ 原始邮件 ------------------ 发件人: "umijs/umi" @.>; 发送时间: 2021年8月30日(星期一) 中午11:07 @.>; @.**@*.**@*.***>; 主题: Re: [umijs/umi] 配置路由,开启layout,路由配置3层,页面不渲染 (#5221)

BoundaryAndCraft/Craft 这个模块里面有加下面这个吗 if ( ['/boundaryandcraft/carft/editbase',].includes(history.location.pathname) ) { return props.children }

没有。那这样的话一个页面好处理。下面模块多了的话不就很麻烦么?配置个路由要改两个地方

我是这么解决的 你可以自己本地 打debugger 测试下 如果不用这个方法 欢迎提供另外的方法

好的谢谢了。我也想找个更好的方法来解决这个问题

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

LoveEocding commented 2 years ago

子路由必须是是父路由的子级。比如子: a/b/c 父一定是:a/b. ![Uploading image.png…]()

LoveEocding commented 2 years ago

子路由。必须是在父路由基础上加。export enum WorkLoad { BASE = '/workload', DEPLOY = '/workload/deploy', DEPLOY_CREATE = '/workload/deploy/create', DEPLOY_DETAIL = '/workload/deploy/detail', CONFIG_BASE ='/workload/config', CONFIG_LIST = '/workload/config/list', ENTRY_DETAIL='/workload/config/entryDictionary/detail' }

GOWxx commented 2 years ago

子路由。必须是在父路由基础上加。

上面评论里的图片没有上传成功, 可以重新上传一下吗

RicardoUU commented 2 years ago

如果在父级路由配置了components,就会出现子级路由不渲染的问题,因为umi默认采用的是严格路由模式, 但是只要父级配置了routes,在预构建的.umi/core/routes.ts 中可以发现 exact属性是没有的,所以相当于exact:false。如果父级配置了component属性,子级组件就会默认渲染到父级组件的props. children,然而父级组件没有对props. children进行处理,这个时候你就会发现无论访问哪个子级路由显示的都是父级。如果手动设置父级的exact:true,得到的就是404。

解决办法:

1、父级路由不设置componet属性,在routes配置中增加一项和父级path一样的配置 也就是

{
    path: '/a',
    name: 'a',
    icon: 'smile',
    hideChildrenInMenu:true,
    routes: [
       {
             path: '/a',
             name: 'a.index',
             icon: 'smile',
             component: './a'
       }
       {
             path: '/a/b',
             name: 'a.b',
             icon: 'smile',
             component: './b'
       }
   ]
},

2、使用redirect属性跳转,这种方式的弊端是点击父级路由时跳转会闪屏

{
    path: '/a',
    name: 'a',
    icon: 'smile',
    hideChildrenInMenu:true,
    routes: [
       {
             path: '/a',
             redirect:'/a/index'
       },
       {
             path: '/index',
             name: 'a.index',
             icon: 'smile',
             component: './a'
       },
       {
             path: '/a/b',
             name: 'a.b',
             icon: 'smile',
             component: './b'
       }
   ]
},
cuijiudai commented 2 years ago

如果在父级路由配置了components,就会出现子级路由不渲染的问题,因为umi默认采用的是严格路由模式, 但是只要父级配置了routes,在预构建的.umi/core/routes.ts 中可以发现 exact属性是没有的,所以相当于exact:false。如果父级配置了component属性,子级组件就会默认渲染到父级组件的props. children,然而父级组件没有对props. children进行处理,这个时候你就会发现无论访问哪个子级路由显示的都是父级。如果手动设置父级的exact:true,得到的就是404。

解决办法:

1、父级路由不设置componet属性,在routes配置中增加一项和父级path一样的配置 也就是

{
    path: '/a',
    name: 'a',
    icon: 'smile',
    hideChildrenInMenu:true,
    routes: [
       {
             path: '/a',
             name: 'a.index',
             icon: 'smile',
             component: './a'
       }
       {
             path: '/a/b',
             name: 'a.b',
             icon: 'smile',
             component: './b'
       }
   ]
},

2、使用redirect属性跳转,这种方式的弊端是点击父级路由时跳转会闪屏

{
    path: '/a',
    name: 'a',
    icon: 'smile',
    hideChildrenInMenu:true,
    routes: [
       {
             path: '/a',
             redirect:'/a/index'
       },
       {
             path: '/index',
             name: 'a.index',
             icon: 'smile',
             component: './a'
       },
       {
             path: '/a/b',
             name: 'a.b',
             icon: 'smile',
             component: './b'
       }
   ]
},

microApp 的情况下,第二种方法 redirect 没作用了,没有执行跳转。

wohaiwo commented 2 years ago

之前用的是 umi 脚手架跑的 config.js 里面的 配置的 routes 可以是一级结构
只需要在 BasicLayout.jsx 里面 调用的 ProLayout 配置的 route方法里面配置对应的 层级结构 就能实现面包屑和路由跳转 也不需要在对应路由添加 child 判断

cuijiudai commented 2 years ago

@chenshuai2144 帅哥,能不能解决下这个问题。太常见了问题了

cuijiudai commented 2 years ago

设置了选项 layout: 'mix', splitMenus: true, 需求是 动态加载子应用 和 子应用路由 的情况:

routes 配置如下:

{
  name: '子 vue 应用',
  path: '/qk-vue-app',
  microApp: 'qk-vue-app',
  meta: {  
    redirect: '/qk-vue-app/index/about'  // important  在meta 配置跳转地址。
  },
  routes: [
    {
      name: '子 vue 应用 index',
      path: '/qk-vue-app/index',
      routes: [
        {
          name: '子 vue index about',
          path: '/qk-vue-app/index/about',
        },
      ],
    },
    {
      name: '子 vue 应用 about',
      path: '/qk-vue-app/about',
    },
  ]
}

在 app.tsx 添加

//解决子应用 redirect 参数不跳转问题
export function onRouteChange({ matchedRoutes, location, action }: any) {
  const matched = matchedRoutes[matchedRoutes.length - 1];
  if (
    matched.route.microApp &&
    matched.route.meta?.redirect &&
    matched.route.meta?.redirect !== location.pathname //防止死循环
  ) {
    history.push(matched.route.meta.redirect);
  }
}

我试着可以跳转过去了。