当前位置: 首页 > 工具软件 > umi > 使用案例 >

【umi】umi初探

程瑞
2023-12-01

前言

  • 某次听公开课看别人用这玩意,感觉很nb,稍微学一下。

umijs

  • 是一个类似next.js的react框架,约定pages 目录下的文件即路由,而文件则导出 react 组件。
  • 官网仓库
  • 官网文档
  • 中文可发音为乌米,不过图标为啥是个白米饭。。

安装运行

  • 先不用cli构建,安装全局命令umi
cnpm install -g umi
  • 使用umi g page index可以生成index页面。一共2个文件,一个是js一个是css。
  • umi g 是 umi generate 的别名,可用于快速生成 component、page、layout 等,并且可在插件里被扩展,比如 umi-plugin-dva 里扩展了 dva:model,然后就可以通过 umi g dva:model foo 快速 dva 的 model。
  • 每个js文件都是个路由,会导出成react组件。
  • 下面就运行试试,修改package.json里的script命令为:
  "scripts": {
    "dev": "umi dev",
    "build": "umi build",
    "test": "umi test"
  },
  • 然后用npm run dev试试。根路径就会去访问index.js这个文件,再建个文件比如user,路径上加user即可访问到。
  • 启动后会发现目录里多了个叫.umi的文件夹,里面就是umi扫描pages生成的文件,最主要的就是路由之类,可以看见在router文件里面,路由里需要哪个文件看的很清楚。它还把路由信息挂到window上了,直接使用window.g_routes可以看路由。里面有个patchRoutes是运行时修改路由,就是动态修改路由。

跳转路由

  • 里面跳转路由方式差不多。
  • 第一种方式就是使用Link。

import styles from './index.css';
import Link from 'umi/link'
export default function () {  
  return (
    <div className={styles.normal}>
      <h1>Page index</h1>
      <Link to="/user">/user</Link>
    </div>
  );
}
  • 跟通常使用react-router-dom的link一样。
  • 还有种方法使用router进行跳转:
import styles from './user.css';
import router from 'umi/router'
export default function () {
  console.log(router);
  return (
    <div className={styles.normal}>
      <h1>Page user</h1>
      <button onClick={() => router.push('/xcxc')}>push</button>
    </div>
  );
}
  • 打印router可以看见有go goback goForward replace push这些方法,这个就是history的方法。

全局路由

  • 约定 src/layouts/index.js 为全局路由,返回一个 React 组件,通过 props.children 渲染子组件。
  • 这个全局路由,就是渲染别的路由前必须渲染的。
  • pages需要放到src下,这样才能生效。

src/layouts/index.js

import Link from 'umi/link'
export default function (props) {
    return (
        <div >
            <h1>layout</h1>
            <Link to="/">/</Link>
            <Link to="/user">/user</Link>
            <div>{props.children}</div>
        </div>
    );
}

嵌套路由

  • 嵌套路由有点像小型的全局路由。就是在这个路由下必须渲染这个组件。
  • 约定是需要的目录下写个_layout.js文件。这个路由下的所有路由都会通过它来渲染。

src/pages/product/_layout.js

import Link from 'umi/link'
export default function (props) {
    return (
        <div >
            <h1>productA</h1>
            <Link to="/product/productA">/productA</Link>
            <Link to="/product/productB">/productB</Link>
            <div>{props.children}</div>
        </div>
    );
}
  • src/pages/product/productA和B就不放了,一个样。出来的效果就是productA和B都会在这个props.chilren里渲染。

动态路由

  • umi 里约定,带 $ 前缀的目录或文件为动态路由。

src/pages/product/$id.js

export default function (props) {
    return (
        <div >
            ID:{props.match.params.id}
        </div>
    );
}
  • 我们改一下_layout把跳转写出来:
import Link from 'umi/link'
export default function (props) {
    return (
        <div >
            <h1>productA</h1>
            <Link to="/product/productA">/productA</Link>
            <Link to="/product/productB">/productB</Link>
            <Link to="/product/1">/1</Link>
            <Link to="/product/2">/2</Link>
            <div>{props.children}</div>
        </div>
    );
}
  • 这样点1或者点2都会指向$id那个组件,那个组件通过props.match.params.id拿到参数。需要别的可以把props打印出来看。

权限路由

  • umi 的权限路由是通过配置路由的 Routes 属性来实现。约定式的通过 yaml 注释添加。
/**
 * title: privatepage
 * Routes:
 *   - ./PrivateRouter.js
 */
export default function (props) {
    return (
        <div >
            <h1>Private page</h1>
        </div>
    );
}
  • ./PrivateRouter.js是相对于根目录的位置。就是跟package.json一个位置。
  • yaml注释必须顶格写,不能空一行或者import完再写这个。
  • yaml语法格式化工具转换后发现其实是这个:
{ title: 'privatepage', Routes: [ './PrivateRouter.js' ] }
  • 这个语法还是挺常用的,前面在docker配置里用过。

PrivateRouter.js

import { Route, Redirect } from 'react-router-dom'
export default ({ render}) => {
    return (
        <Route render={
            (props) => localStorage.getItem('login') ? render(props) : <Redirect to='/' />
        }>
        </Route>
    )
}
  • 这个就是在访问Private page时会先走一遍PrivateRouter,里面有个条件渲染,如果localstorage里有login的键,那么就渲染请求的路径,否则就重定向回主页。
  • 权限路由就这么多内容了。
 类似资料: