umi学习笔记

在 Ant Design Pro 中,因为我们的底层框架是 umi,而它自带了代理请求功能,通过代理请求就能够轻松处理数据模拟的功能。

配置式路由和约定式路由

Umi的路由既支持配置样式,又支持约定样式。配置样式是对于现实的低头,也是大部分用户在用的,因为他功能强大;约定样式是我们希望走去的方向,因为他简洁优雅。

.umi临时文件

  1. + .umi
  2. + core #内部插件生成
  3. + pluginA #外部插件生成
  4. +预设B #外部插件生成
  5. + umi.ts #入口文件

临时文件是Umi框架中非常重要的一部分,框架或插件会根据你的代码生成临时文件,这些原来需要放在项目里的脏乱差的部分都被藏在了这里。

您可以在这里调试代码,但不要在.git仓库里提交他,因为他的临时性,每次启动umi时都会被删除并重新生成。

Umi 在 .umirc.ts 或 config/config.ts 中配置项目和插件,支持 es6。一份常见的配置如下,

配置文件

推荐在 .umirc.ts 中写配置。如果配置比较复杂需要拆分,可以放到 config/config.ts 中,并把配置的一部分拆出去,比如路由。

两者二选一,.umirc.ts 优先级更高。

TypeScript 提示

如果你想在写配置时也有提示,可以通过 umi 的 defineConfig 方法定义配置,

import { defineConfig } from 'umi';
export default defineConfig({
  routes: [
    { path: '/', component: '@/pages/index' },
  ],
});

运行时配置

运行时配置和配置的区别是他跑在浏览器端,基于此,我们可以在这里写函数、jsx、import 浏览器端依赖等等,注意不要引入 node 依赖。

约定 src/app.tsx 为运行时配置。

patchRoutes({ routes })

路由

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

配置路由

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

export default {
  routes: [
    { exact: true, path: '/', component: 'index' },
    { exact: true, path: '/user', component: 'user' },
  ],
}

wrappers

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

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

export default {
  routes: [
    { path: '/user', component: 'user',
      wrappers: [
        '@/wrappers/auth',
      ],
    },
    { path: '/login', component: 'login' },
  ]
}

然后在 src/wrappers/auth 中,

export default (props) => {
  const { isLogin } = useAuth();
  if (isLogin) {
    return <div>{ props.children }</div>;
  } else {
    redirectTo('/login');
  }
}

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

Link 组件

import { Link } from 'umi';
export default () => (
  <div>
    <Link to="/users">Users Page</Link>
  </div>
);

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

Link 只用于单页应用的内部跳转,如果是外部地址跳转请使用 a 标签
路由组件参数

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

  • match,当前路由和 url match 后的对象,包含 params、path、url 和 isExact 属性
  • location,表示应用当前出于哪个位置,包含 pathname、search、query 等属性
  • history,同 api#history 接口
  • route,当前路由配置,包含 path、exact、component、routes 等
  • routes,全部路由信息
export default function(props) {
  console.log(props.route);
  return <div>Home Page</div>;
}

传递参数给子路由

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

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

约定式路由

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

动态路由

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

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',
  },
];

嵌套路由

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

页面跳转

声明式

通过 Link 使用,通常作为 React 组件使用。

import { Link } from 'umi';
export default () => (
  <Link to="/list">Go to list page</Link>
);

命令式

通过 history 使用,通常在事件处理中被调用。

import { history } from 'umi';
function goToListPage() {
  history.push('/list');
}

也可以直接从组件的属性中取得 history

export default (props) => (