约定式路由

除配置式路由外,Umi 也支持约定式路由。约定式路由也叫文件路由,就是不需要手写配置,文件系统即路由,通过目录和文件及其命名分析出路由配置。

如果没有 routes 配置,Umi 会进入约定式路由模式,然后分析 src/pages 目录拿到路由配置。

比如以下文件结构:

  1. .
  2. └── pages
  3. ├── index.tsx
  4. └── users.tsx

会得到以下路由配置,

  1. [
  2. { exact: true, path: '/', component: '@/pages/index' },
  3. { exact: true, path: '/users', component: '@/pages/users' },
  4. ]

需要注意的是,满足以下任意规则的文件不会被注册为路由,

  • ._ 开头的文件或目录
  • d.ts 结尾的类型定义文件
  • test.tsspec.tse2e.ts 结尾的测试文件(适用于 .js.jsx.tsx 文件)
  • componentscomponent 目录
  • utilsutil 目录
  • 不是 .js.jsx.ts.tsx 文件
  • 文件内容不包含 JSX 元素

动态路由

约定 [] 包裹的文件或文件夹为动态路由。

比如:

  • src/pages/users/[id].tsx 会成为 /users/:id
  • src/pages/users/[id]/settings.tsx 会成为 /users/:id/settings

举个完整的例子,比如以下文件结构,

  1. .
  2. └── pages
  3. └── [post]
  4. ├── index.tsx
  5. └── comments.tsx
  6. └── users
  7. └── [id].tsx
  8. └── index.tsx

会生成路由配置,

  1. [
  2. { exact: true, path: '/', component: '@/pages/index' },
  3. { exact: true, path: '/users/:id', component: '@/pages/users/[id]' },
  4. { exact: true, path: '/:post/', component: '@/pages/[post]/index' },
  5. {
  6. exact: true,
  7. path: '/:post/comments',
  8. component: '@/pages/[post]/comments',
  9. },
  10. ];

动态可选路由

暂不支持。

嵌套路由

Umi 里约定目录下有 _layout.tsx 时会生成嵌套路由,以 _layout.tsx 为该目录的 layout。layout 文件需要返回一个 React 组件,并通过 props.children 渲染子组件。

比如以下目录结构,

  1. .
  2. └── pages
  3. └── users
  4. ├── _layout.tsx
  5. ├── index.tsx
  6. └── list.tsx

会生成路由,

  1. [
  2. { exact: false, path: '/users', component: '@/pages/users/_layout',
  3. routes: [
  4. { exact: true, path: '/users', component: '@/pages/users/index' },
  5. { exact: true, path: '/users/list', component: '@/pages/users/list' },
  6. ]
  7. }
  8. ]

全局 layout

约定 src/layouts/index.tsx 为全局路由。返回一个 React 组件,并通过 props.children 渲染子组件。

比如以下目录结构,

  1. .
  2. └── src
  3. ├── layouts
  4. └── index.tsx
  5. └── pages
  6. ├── index.tsx
  7. └── users.tsx

会生成路由,

  1. [
  2. { exact: false, path: '/', component: '@/layouts/index',
  3. routes: [
  4. { exact: true, path: '/', component: '@/pages/index' },
  5. { exact: true, path: '/users', component: '@/pages/users' },
  6. ],
  7. },
  8. ]

不同的全局 layout

你可能需要针对不同路由输出不同的全局 layout,Umi 不支持这样的配置,但你仍可以在 src/layouts/index.tsx 中对 location.path 做区分,渲染不同的 layout 。

比如想要针对 /login 输出简单布局,

  1. export default function(props) {
  2. if (props.location.pathname === '/login') {
  3. return <SimpleLayout>{ props.children }</SimpleLayout>
  4. }
  5. return (
  6. <>
  7. <Header />
  8. { props.children }
  9. <Footer />
  10. </>
  11. );
  12. }

404 路由

约定 src/pages/404.tsx 为 404 页面,需返回 React 组件。

比如以下目录结构,

  1. .
  2. └── pages
  3. ├── 404.tsx
  4. ├── index.tsx
  5. └── users.tsx

会生成路由,

  1. [
  2. { exact: true, path: '/', component: '@/pages/index' },
  3. { exact: true, path: '/users', component: '@/pages/users' },
  4. { component: '@/pages/404' },
  5. ]

这样,如果访问 /foo//users 都不能匹配,会 fallback 到 404 路由,通过 src/pages/404.tsx 进行渲染。

扩展路由属性

支持在代码层通过导出静态属性的方式扩展路由。

比如:

  1. function HomePage() {
  2. return <h1>Home Page</h1>;
  3. }
  4. HomePage.title = 'Home Page';
  5. export default HomePage;

其中的 title 会附加到路由配置中。