1. 配置式路由
在配置文件(.umirc.ts
或者 config/config.ts
)中通过 routes
对象配置路由,就是配置式路由。如果没有 routes
配置项,则自动对 src/pages
目录生成约定式路由。
2. 约定式路由
约定式路由也叫文件路由,就是不需要手写配置,文件系统即路由,通过目录和文件及其命名分析出路由配置。
如果没有 routes 配置,Umi 会进入约定式路由模式,然后分析 src/pages
目录拿到路由配置。
需要注意的是,满足以下任意规则的文件不会被注册为路由,
- 以
.
或_
开头的文件或目录 components
和component
目录utils
和util
目录- 文件内容不包含 JSX 元素
1) 动态路由
约定 []
包裹的文件或文件夹为动态路由。
比如:
src/pages/users/[id].tsx
会成为/users/:id
src/pages/users/[id]/settings.tsx
会成为/users/:id/settings
举个完整的例子,比如以下文件结构,
.
└── pages
└── [post]
├── index.tsx
└── comments.tsx
└── users
└── [id].tsx
└── index.tsx
会生成路由配置,
[
{ exact: true, path: '/', component: '@/pages/index' },
{ exact: true, path: '/users/:id', component: '@/pages/users/[id]' },
{ exact: true, path: '/:post/', component: '@/pages/[post]/index' },
{
exact: true,
path: '/:post/comments',
component: '@/pages/[post]/comments',
},
];
动态路由会根据匹配到的动态参数生成 url
,然后可以通过 props.match.params.
取到动态数据。例如在 src/pages/users/[id].tsx
中,通过 props.match.params.id
就可以获取到 id
的值。
2) 动态可选路由
约定 [ $]
包裹的文件或文件夹为动态可选路由。
例如:src/pages/users/[id$].tsx
动态可选路由和动态路由的区别,就在于动态路由如果没有动态参数,不会切换到路由对应的页面。而动态可选路由,没有动态参数也会展示默认页面内容。
例如当我们访问 /users/
,如果是动态路由就看不到任何内容,而动态可选路由就可以看到相对应的页面默认内容。
3) 嵌套路由
Umi 里约定目录下有 _layout.tsx
时会生成嵌套路由,以 _layout.tsx
为该目录的 layout。layout 文件需要返回一个 React 组件,并通过 props.children
渲染子组件。
比如以下目录结构,
.
└── pages
└── users
├── _layout.tsx
├── index.tsx
└── list.tsx
会生成路由,
[
{
exact: false, path: '/users', component: '@/pages/users/_layout',
routes: [
{ exact: true, path: '/users', component: '@/pages/users/index' },
{ exact: true, path: '/users/list', component: '@/pages/users/list' },
]
}
]
一个简单的 _layout.tsx
范例:
const layout: React.FC = (props) => {
return (
<>
<div>user page</div>
{ props.children }
</>
);
};
export default layout;
4) 全局 layout
约定 src/layouts/index.tsx
为全局路由。同样,返回一个 React 组件,并通过 props.children
渲染子组件。
一个自定义的全局 layout
如下:
import ProLayout from '@ant-design/pro-layout';
import { IRouteComponentProps } from 'umi';
const Layout: React.FC<IRouteComponentProps> = (props) => {
return (
<ProLayout>
<div>layout...</div>
{ props.children }
</ProLayout>
)
};
export default Layout;
5) 不同的全局 layout
你可能需要针对不同路由输出不同的全局 layout,Umi 不支持这样的配置,但你仍可以在 src/layouts/index.tsx
中对 location.path
做区分,渲染不同的 layout 。
比如想要针对 /login
输出简单布局:
import ProLayout from '@ant-design/pro-layout';
import { IRouteComponentProps } from 'umi';
const Layout: React.FC<IRouteComponentProps> = (props) => {
if (props.location.pathname === '/login') {
return <div>{ props.children }</div>
}
return (
<ProLayout>
<div>layout...</div>
{ props.children }
</ProLayout>
)
};
export default Layout;
需要注意的是,只是 约定式路由 不能设置多个全局layout文件,只能在index.tsx
中对location.path
做区分。如果是 配置式路由 的话,是完全可以给不同路由页面设置多个layout的(在路由配置文件里设置)。
5) 404 路由
约定 src/pages/404.tsx
为 404 页面,需返回 React 组件。
如果访问的路由和已按约定生成的路由都不能匹配,会 fallback 到 404 路由,通过 src/pages/404.tsx
进行渲染。
一个典型的 AntDesign
404路由页面:
import { Button, Result } from 'antd';
import React from 'react';
import { history } from 'umi';
const NoFoundPage: React.FC = () => (
<Result
status="404"
title="404"
subTitle="Sorry, the page you visited does not exist."
extra={
<Button type="primary" onClick={() => history.push('/')}>
Back Home
</Button>
}
/>
);
export default NoFoundPage;
上一篇:UmiJS 3.X实战从头开始(三):配置与运行时配置
下一篇:UmiJS 3.X实战从头开始(五):插件
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。