umi框架的使用

介绍umi

umi官方文档

初探

对比以往使用的 create-react-app 搭建react项目,根据需要我们还得集合webpack打包,或者引入redux状态管理器等,而umi ---
通过 create-umi提供脚手架能力,
然后我们可以选择需要生成的项目类型:

  • app,通用项目脚手架,支持选择是否启用 TypeScript,以及 umi-plugin-react 包含的功能
  • ant-design-pro,仅包含 ant-design-pro 布局的脚手架,具体页面可通过 umi block 添加
  • block,区块脚手架
  • plugin,插件脚手架
  • library,依赖(组件)库脚手架,基于 umi-plugin-library
    之后选择是否需要支持typescript
    然后选择需要的功能:
  • antd: UI框架,启用后实现antd, antd-mobile 和 antd-pro 的按需编译,无需要手动配置。
  • dva: 基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-router 和 fetch,所以也可以理解为一个轻量级的应用框架
  • code splitting: 是否代码分包
  • dll: 通过 webpack 的 dll 插件预打包一份 dll 文件来达到二次启动提速的目的
    按上下箭头移动,并按 空格 键选中。

确定后,会根据选择自动创建好目录和文件

安装依赖,yarn start启动项目。

路由

umi 以路由为基础的,支持类 next.js 的约定式路由,以及各种进阶的路由功能,并以此进行功能扩展,比如支持路由级的按需加载

(1) 无需手动配置路由
根据pages目录自动生成路由配置,会根据 src / pages 下 文件名自动生成路由
(也可以配置.umirc.js中的 routes 属性,此配置项存在时则不会对 src/pages 目录做约定式的解析)
(2) 其他基础知识:

  • 动态路由:带 $ 前缀的目录或文件。
    目录结构:

      + pages/
      + $post/
        - index.js
        - comments.js
      + users/
        $id.js
      - index.js
    

    会生成的路由配置:

      [
        { path: '/', component: './pages/index.js' },
        { path: '/users/:id', component: './pages/users/$id.js' },
        { path: '/:post/', component: './pages/$post/index.js' },
        { path: '/:post/comments', component: './pages/$post/comments.js' },
      ]
    
  • 可选的动态路由:
    约定动态路由如果带 $ 后缀,则为可选动态路由。

(3)常用的路由操作

  import Link from 'umi/link';
  import router from 'umi/router';
  • 普通使用
    <Link to="/list">跳转</Link>

  • 带参数
    <Link to="/list?a=b">跳转</Link>

  • 包含子组件
    <Link to="/list?a=b"><button>跳转</button></Link>

  • 点击跳转
    <button onClick={() => router.push('/list')}>跳转</button>

  • router.push

         // 普通跳转,不带参数
          router.push('/list');
          // 带参数
          router.push('/list?a=b');
          router.push({ pathname: '/list', query: { a: 'b' } });
    
  • router.replace

  • router.go(n)
    往前或者往后跳指定页数。

  • router.goBack()
    后退一页

  • umi/redirect
    重定向

      import Redirect from 'umi/redirect';
      <Redirect to="/login" />;
    
  • withRouter
    当组件需要路由参数时,使用withRouter可以给当前组件传入路由参数,将react-router的history、location、match三个对象传入props对象上,此时就可以使用this.props

布局

(1)全局layout
约定 src/layouts/index.js 为全局路由,返回一个 React 组件,通过 props.children 渲染子组件。
比如:

    export default function(props) {
      return (
        <>
          <Header />
          { props.children }
          <Footer />
        </>
      );
    }

(2)不同的全局layout
可以在 layouts/index.js 对 location.path 做区分,渲染不同的 layout 。
比如想要针对 /login 输出简单布局:

  export default function(props) {
    if (props.location.pathname === '/login') {
      return <SimpleLayout>{ props.children }</SimpleLayout>
    }

    return (
      <>
        <Header />
        { props.children }
        <Footer />
      </>
    );
  }

(3)尝试
要求: 登录页和首页显示不同的布局


根据路由渲染不同的布局

同样对 location.path 做区分,但是如果是动态路由或者嵌套路由这样的匹配是有漏洞的。

优化后:
配置路由对应的布局,默认使用NavigatorLayout

    const routeLayoutMap = [{
      matches: ['/users', '/login', '/contact-sale'],
      component: BlankLayout,
    }, {
      matches:[],
      component: NavigatorLayout,
    }];

    const res = routeLayoutMap.find(({ matches }) => {
        return checkRouteMatch(matches, location.pathname)
      });
      const layout = res ? res.component : NavigatorLayout
      return React.createElement(layout, props);
    }

根据正则判断

    function checkRouteMatch (routes, pathname) {
      const _routes = routes.map(one => {
        if (isString(one) || isRegExp(one)) one = { match: one }
        if (!isObject(one)) return {}
        const { match, exclude } = one
        return {
          match,
          exclude: (isArray(exclude) || !exclude) ? exclude : [exclude]
        };
      })
      return _routes.some(({ match, exclude }) => {
        function check (rule, value) {
          if (isString(rule)) return value.includes(rule);
          if (isRegExp(rule)) return rule.test(value);
          return false;
        }
        const res = check(match, pathname)
        if (!res) return false;
        if (!isArray(exclude) || !exclude.length) return res;
        return !exclude.some(one => check(one, pathname))
      })
    }

mock

用之前先把mock使用示例看看==>mock.js文档
(1)在umi中使用mock:

  • 新建mock数据:
    在 mock 文件下新建文件 users.js 为保存mock数据的一个文件。

    import mockjs from 'mockjs';
    
    let dataSource = mockjs.mock({
      'list|15-30': [{
          'id': () => mockjs.Random.guid(),
          'name': /[a-zA-Z0-9]{4,8}/,
          'email': /[a-zA-Z0-9]{4,8}@test\.com/,
          'website': /[a-zA-Z0-9]{4,8}/
      }]
    }).list;
    
    export default {
      'GET /api/users': (req, res) => {
        const { page = 0, size = 10 } = req.query
        const _page = parseInt(page, 10)
        const _size = parseInt(size, 10)
        const data = dataSource.slice(_page * _size, (_page + 1) * _size);
        res.json({
          content: data,
          number: _page,
          size: _size,
          totalElements: dataSource.length,
        })
      },
    }
    
  • 调用数据
    输入路径可直接获取数据,:/api/users

  • 排除 mock 目录下不作 mock 处理的文件。
    在config/config.start-dev.js文件中使用exclude
    mock: {
    exclude: ['mock/login.js']
    },

其他探索...(后期更新)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容