路由

在 Umi 中,应用都是单页应用,页面地址的跳转都是在浏览器端完成的,不会重新请求服务端获取 html,html 只在应用初始化时加载一次。所有页面由不同的组件构成,页面的切换其实就是不同组件的切换,你只需要在配置中把不同的路由路径和对应的组件关联上。

配置路由

在配置文件中通过 routes 进行配置,格式为路由信息的数组。

比如:

  1. export default {
  2. routes: [
  3. { exact: true, path: '/', component: 'index' },
  4. { exact: true, path: '/user', component: 'user' },
  5. ],
  6. }

path

  • Type: string | string[]

配置可以被 path-to-regexp@^1.7.0 理解的路径或路由数组。

component

  • Type: string

配置 location 和 path 匹配后用于渲染的 React 组件路径。可以是绝对路径,也可以是相对路径,如果是相对路径,会从 src/pages 开始找起。

如果指向 src 目录的文件,可以用 @,也可以用 ../。比如 component: '@/layouts/basic',或者 component: '../layouts/basic',推荐用前者。

exact

  • Type: boolean
  • Default: false

表示是否严格匹配,即 location 是否和 path 完全对应上。

比如:

  1. export default {
  2. routes: [
  3. // url 为 /one/two 时匹配失败
  4. { path: '/one', exact: true },
  5. // url 为 /one/two 时匹配成功
  6. { path: '/one' },
  7. { path: '/one', exact: false },
  8. ],
  9. }

routes

配置子路由,通常在需要为多个路径增加 layout 组件时使用。

比如:

  1. export default {
  2. routes: [
  3. { path: '/login', component: 'login' },
  4. {
  5. path: '/',
  6. component: '@/layouts/index',
  7. routes: [
  8. { path: '/list', component: 'list' },
  9. { path: '/admin', component: 'admin' },
  10. ],
  11. },
  12. ],
  13. }

然后在 src/layouts/index 中通过 props.children 渲染子路由,

  1. export default (props) => {
  2. return <div style={{ padding: 20 }}>{ props.children }</div>;
  3. }

这样,访问 /list/admin 就会带上 src/layouts/index 这个 layout 组件。

redirect

  • Type: string

配置路由跳转。

比如:

  1. export default {
  2. routes: [
  3. { exact: true, path: '/', redirect: '/list' },
  4. { exact: true, path: '/list', component: 'list' },
  5. ],
  6. }

访问 / 会跳转到 /list,并由 src/pages/list 文件进行渲染。

wrappers

  • Type: string[]

配置路由的高阶组件封装。

比如,可以用于路由级别的权限校验:

  1. export default {
  2. routes: [
  3. { path: '/user', component: 'user',
  4. wrappers: [
  5. '@/wrappers/auth',
  6. ],
  7. },
  8. { path: '/login', component: 'login' },
  9. ]
  10. }

然后在 src/wrappers/auth 中,

  1. export default (props) => {
  2. const { isLogin } = useAuth();
  3. if (isLogin) {
  4. return <div>{ props.children }</div>;
  5. } else {
  6. redirectTo('/login');
  7. }
  8. }

这样,访问 /user,就通过 useAuth 做权限校验,如果通过,渲染 src/pages/user,否则跳转到 /login,由 src/pages/login 进行渲染。

title

  • Type: string

配置路由的标题。

页面跳转

  1. import { history } from 'umi';
  2. // 跳转到指定路由
  3. history.push('/list');
  4. // 带参数跳转到指定路由
  5. history.push('/list?a=b');
  6. history.push({
  7. pathname: '/list',
  8. query: {
  9. a: 'b',
  10. },
  11. });
  12. // 跳转到上一个路由
  13. history.goBack();

hash 路由

详见 配置#history

Link 组件

比如:

  1. import { Link } from 'umi';
  2. export default () => (
  3. <div>
  4. <Link to="/users">Users Page</Link>
  5. </div>
  6. );

然后点击 Users Page 就会跳转到 /users 地址。

注意:

  • Link 只用于单页应用的内部跳转,如果是外部地址跳转请使用 a 标签

路由组件参数

路由组件可通过 props 获取到以下属性,

  • match,当前路由和 url match 后的对象,包含 paramspathurlisExact 属性
  • location,表示应用当前出于哪个位置,包含 pathnamesearchquery 等属性
  • history,同 api#history 接口
  • route,当前路由配置,包含 pathexactcomponentroutes

比如:

  1. export default function(props) {
  2. console.log(props.route);
  3. return <div>Home Page</div>;
  4. }

传递参数给子路由

通过 cloneElement,一次就好(Umi 2 时需要两次)。

  1. import React from 'react';
  2. export default function Layout(props) {
  3. return React.Children.map(props.children, child => {
  4. return React.cloneElement(child, { foo: 'bar' });
  5. });
  6. }