• 【Umi 一】 Umi 搭建配置


    蚂蚁金服开源的企业级React框架,并不是UI框架

    1.特性

    1. 开箱即用,内置 reactreact-router ...
    2. 类似 next.js 且功能完备的路由约定,同时也支持手动配置路由的方式;
    3. 完善的插件体系,高性能,通过插件支持PWA、以路由为单元的code splitting等等;
    4. 支持静态页面导出,适配各种环境,如中台业务、无线业务、egg、支付宝钱包
    5. 开发启动快,支持一键开启dll
    6. 一键兼容IE9、基于 umi-plugin-polyfills
    7. 支持TypeScript
    8. dva 数据流的深入融合,支持duck directory、model的自动加载、code splitting等等
    2.dva 是React应用框架,封装了 ReduxRedux-sagaReact-router 三个React工具库,目前 React 最流行的数据流解决放案;


    1. State:一个对象,保存整个应用状态;
    2. View:React组件构成的视图层;
    3. Action:一个对象,描述事件
    4. connect():绑定```State``````View```
    5. dispatch():发送```Action``````State```

    3.dvaumi 的约定

            1.src 源码:pages(页面)、components(组件)、layout(布局)、model(数据模型)

            2.config 配置

            3.mock 数据模拟

            4.test 测试

    4.全局安装脚手架: npm i umi -g
     

    快速上手

    1、创建一个项目目录:mkdir myumi
    2、cd myumi 
    3、npm init:生成 package.json
    "scripts": {
        "start": "umi dev",
        "build": "umi build"
    }
    4、创建 src 目录,生成 pages 目录,默认使用约定式路由
    cd src
    umi g page index  // index.js和index.css
    umi g page about  // bout.js和about.css

    5、运行项目:npm start,自动编译生成页面配置 /src/pages/.umi 目录,且项目是热部署;

    http://localhost:8000/  --> index.js
    http://localhost:8000/about  --> about.js

    6、引入公共 css (根据个人需求,可要可不要)

    在 src 目录下新建 global.css/.less 

    7、创建全局布局 layouts,如公共头部、尾部  (根据个人需求,可要可不要)

    src/layouts 目录中的 index.js 将成为项目的定级布局页面,使用 {props.children} 显示 src/pages 目录中的组件。

    在 src 目录下,创建文件夹 layouts
    在 layouts 目录下,创建 index.js、index.less
    import styles from './index.css';
    import {Layout} from 'antd';
    const {Header, Content, Footer} = Layout;
    
    export default (props) => {
        return (
            <Layout>
                <Header>
                    <div style={{color: 'white'}}>王者资料库</div>
                </Header>
                <Content style={{padding: '0 50px'}}>
                    {props.children}
                </Content>
                <Footer style={{textAlign: 'center'}}>footer</Footer>
            </Layout>
        )
    }

    约定式路由嵌套 (Link、history)

    1、当出现 _layout.js 页面时默认为父组件页面,通过 {props.children} 显示子组件内容;

    2、嵌套路由:/users,创建 pages/users 目录

    umi g page users/_layout    // pages/users/_layout.js、_layout.css

            1.pages/users/_layout.js

    import React from 'react';
    import styles from './_layout.css';
    
    export default (props) => {
      return (
        <div className={styles.normal}>
          <h1 className={styles.title}>Page users/_layout</h1>
          <div>{props.children}</div>
        </div>
      );
    }

            2.为 _layout.js 创建子组件,users 的首页 index.js

     umi g page users/index    // pages/users/index.js、index.css

             3.访问嵌套路由:http://localhost:8000/users

     3、约定 [] 包裹的文件或文件夹为动态路由、users/[name].js 对应路由为 /users/:name

    1. users 目录中,再创建 [name].js、[name].css
    2. 访问 [name].jshttp://localhost:8000/users/xxx

    4、跳转路由 (Link,history)

             1.users/index.js

    import React from 'react';
    import styles from './index.css';
    import {Link} from 'umi';
    
    export default () => {
        const userList = [
            {id: 1, name: 'Tim'}, {id: 2, name: 'Jarry'}
        ]
      return (
        <div>
          <ul>
          {
              userList.map(item => (
                  <li key={item.id}>
                      <Link to={`/users/${item.name}`}>{item.name}</Link>
                  </li>
              ))
          }
          </ul>
        </div>
      );
    }

              2.users/[name].js

    import React from 'react';
    import styles from './[name].css';
    import {history} from 'umi';
    
    export default (props) => {
      return (
        <div>
          <h1 className={styles.title}>Page users/[name]</h1>
          <h2>{props.match.params.name}</h2>
            <button onClick={()=>props.history.goBack()}>返回</button>
        </div>
      );
    }

    配置式路由

    1、配置式路由一旦创建,约定式路由自动失效,umi不会再自动创建路由;

    2、在项目根目录下创建 config 目录,并创建 config.js文件;

    // 没有设置全局 layouts 布局
    export default {
        // 路由配置:路径相对于 src/pages
        routes: [
            {path: '/', component: './index'},
            {path: '/about', component: './about'},
            {
                path: '/users',
                component: './users/_layout',
                routes: [
                    {path: '/users', component: './users/index'},
                    {path: '/users/:name', component: './users/[name]'},
                ]
            },
            {component: './notfound'} // 404页面,上面的所有路由都没有匹配时,则匹配404页面
        ],
    }
    // 设置了全局 layouts 布局
    export default {
        // 路由配置:路径相对于 src/pages
        routes: [
            {
                path: '/', 
                component: '../layouts/index',
                routes: [
                    {path: '/', component: './index'},
                    {path: '/about', component: './about'},
                    {
                        path: '/users',
                        component: './users/_layout',
                        routes: [
                            {path: '/users', component: './users/index'},
                            {path: '/users/:name', component: './users/[name]'},
                        ]
                    },
                ]
            },
        ],
    }

    3、相应地,创建404组件:umi g page notfound

    4、引入ant design UI库

    npm i antd -S
    npm i @umijs/preset-react -D (umi3升级)

             1.config/config.js

        export default {
            //路由配置
            routes: [...],
            antd: {},
        }

              2.使用时需要导入组件,因为是按需加载

    import {Button} from 'antd';
    
    <Button type="success">antd Btn</Button>

    引入dva

    1、dva 主要是软件分层的概念

              1.Page 负责与用户直接交互:渲染页面、接收用户的操作输入,侧重于展示型和交互逻辑;

              2.Model 负责处理业务逻辑,可以理解成一个维护页面数据状态的对象,为 Page 做数据、状态的读写等操作;

        export default {
            namespace: 'goods',  // model的命名空间,区分多个model
            state: [],  //初始状态
            effects: {  //异步操作
            },
            reducers: {}
        }

                3.Service 主要负责与HTTP做接口对接,跟后端做数据交互,读写数据;

    2、dva 已经融合进了 umi,在 config/config.js 中打开 dva 的开关

    antd: {},
    dva: {}

    基本用法

    umi g page goods
    npm i axios -S

    1、路由配置:config/config.js (如果使用约定式路由,则无须配置)

    routes: [
        { path: "/goods", component: "./goods" },
    ]

    2、在项目根目录下创建 mock/goods.js,模拟接收请求,响应数据

    let data = [
      {title: '单页面'},
      {title: '管理项目3'}
    ]
    export default {
      'get /api/goods': function(req, res){
        setTimeout(() => {
          res.json({result: data})
        }, 1000)
      }
    }

    3、Modelsrc/models/goods,js

    import axios from 'axios';
    
    //调接口的逻辑应该放在 Service 层
    function getGoods(){
      return axios.get('/api/goods')
    }
    
    export default{
        namespace: 'goods',  // 命名空间,如果省略,则以文件名作为命名空间
        state: [],
        effects: {
            *getList(action, {call , put}){ // 异步操作
                const res = yield call(getGoods);  // 发起请求
                yield put({type: 'initGoods', payload: res.data.result})  // 派发异步action: initGoods 
            }
        },
        reducers: {
            initGoods(state, action){
                return action.payload
            },
            addGood(state, action){
                return [...state, {title: action.payload.title}]
            },
            delGood(state, action){
                return [...state.slice(0,action.payload.index),...state.slice(action.payload.index+1)];
            }
        }
    }

    4、pages/goods.js

    import React, { Component} from 'react';
    import styles from './goods.css';
    import {connect} from 'dva';
    
    // @connect 必须放在 export default class 前面
    @connect(
      state => ({
        goodList: state.goods, // 从指定命名空间内获取state
        loading: state.loading // 通过loading命名空间获取加载的状态
      }), 
      {
        getList: () => ({
          type: 'goods/getList' // action的type需要以命名空间为前缀,后跟reducer
        }),
        addGood: title => ({
          type: 'goods/addGood',
          payload: {title}
        }),
        delGood: index => (
            {
                type: 'goods/delGood',
                payload: {index}
            }
        )
      }
    )
    
    export default class extends Component{
      componentDidMount(){
        this.props.getList(); // 触发事件,发起请求,获取数据
      }
      render(){
        if(this.props.loading.models.goods){
            // 命名空间goods 的请求在加载中
          return <div>loading</div>
        }
        return (
          <div>
            <ul>
              {
                this.props.goodList.map((good, index) => {
                  return <li key={index}>{good.title}<button style={{marginLeft: '100px', marginBottom: '10px'}} onClick={() => this.props.delGood(index)}>删除</button></li>
                })
              }
            </ul>
            <button onClick={() => this.props.addGood('商品3')}>添加</button>
          </div>
        )
      }
    }

    【常见报错问题】

    1、reactjs页面无法引入umi/link

    【Umi 二】reactjs页面无法引入umi/link

     2、Path must be a string. 

    【Umi 三】 Umi项目启动报错:Path must be a string.

    3、Cannot find module 'umi'

    【Umi 四】 Cannot find module 'umi'

    参考文章:umi

  • 相关阅读:
    CenterNet-TensorRT错误记录
    NAS研究要点分析
    conda如何安装从源下载的离线安装包
    Xavier上pytorch半精度inference问题
    Xavier 使用便携程序
    Xavier疑问
    Python输入(Leetcode
    兴趣爱好
    生活目标
    TX2装机教程
  • 原文地址:https://www.cnblogs.com/rachelch/p/13878202.html
Copyright © 2020-2023  润新知