初识umi

news2024/11/24 10:01:42

一、umi简介

Umi,中文发音为「乌米」,是可扩展的企业级前端应用框架。Umi 以路由为基础的,同时支持配置式路由和约定式路由,保证路由的功能完备,并以此进行功能扩展。然后配以生命周期完善的插件体系,覆盖从源码到构建产物的每个生命周期,支持各种功能扩展和业务需求。

Umi 是蚂蚁集团的底层前端框架,已直接或间接地服务了 10000+ 应用,包括 Java、Node、H5 无线、离线(Hybrid)应用、纯前端 assets 应用、CMS 应用、Electron 应用、Serverless 应用等。他已经很好地服务了我们的内部用户,同时也服务了不少外部用户,包括淘系、飞猪、阿里云、字节、腾讯、口碑、美团等。在 2021 年字节的调研报告中,Umi 是其中 25.33% 开发者的选择。

Umi 有很多非常有意思的特性,比如。

1、企业级,在安全性、稳定性、最佳实践、约束能力方面会考虑更多 2、插件化,啥都能改,Umi 本身也是由插件构成 3、MFSU,比 Vite 还快的 Webpack 打包方案 4、基于 React Router 6 的完备路由 5、默认最快的请求 6、SSR & SSG 7、稳定白盒性能好的 ESLint 和 Jest 8、React 18 的框架级接入 9、Monorepo 最佳实践

官网地址:https://umijs.org/

二、umi环境搭建

1、快速上手

第1步、创建umi项目

首先在终端执行如下命令来创建umi项目

yarn create umi

第2步、项目模板选择

  • simple App:你可以理解为纯净版的Umi,包含umi4文档上关于Guides下的所有功能,但是不包括Umi Max。

  • Ant Design Pro:包含Umi Max的完整功能,均可通过在.umirc.ts 或 config/config.ts中插拔式配置。

  • Vue Simple App:如果你的项目框架是vue则使用该模版。

第3步、选择包管理工具

? Pick Npm Client » - Use arrow-keys. Return to submit.
    npm
    cnpm
    tnpm
>   yarn
    pnpm

第4步、选择资源注册地

? Pick Npm Registry » - Use arrow-keys. Return to submit.
    npm
>   taobao

第5步、启动项目

yarn dev

第6步、运行项目

在浏览器地址栏输入:http://localhost:8000

2、目录结构

.
├── config
│   └── config.ts
├── dist
├── mock
│   └── app.ts|tsx
├── src
│   ├── .umi
│   ├── .umi-production
│   ├── app.ts
│   ├── layouts
│   │   ├── BasicLayout.tsx
│   │   ├── index.less
│   ├── models
│   │   ├── global.ts
│   │   └── index.ts
│   ├── pages
│   │   ├── index.less
│   │   └── index.tsx
│   ├── utils // 推荐目录
│   │   └── index.ts
│   ├── services // 推荐目录
│   │   └── api.ts
│   ├── global.ts
│   ├── global.(css|less|sass|scss)
│   ├── favicon.(ico|gif|png|jpg|jpeg|svg|avif|webp)
│   └── loading.tsx
├── node_modules
│   └── .cache
│       ├── bundler-webpack
│       ├── mfsu
│       └── mfsu-deps
├── .env
├── plugin.ts 
├── .umirc.ts // 与 config/config 文件 2 选一
├── package.json
├── tsconfig.json
└── typings.d.ts
  • .umi:dev 临时目录,需添加到 .gitignore

  • .umirc.ts:配置文件,包含 Umi 内置功能和插件的配置。 config/config.ts 文件功能相同,2 选 1 。.umirc.ts 文件优先级较高

  • config/config.ts:配置文件,包含 Umi 内置功能和插件的配置。 config/config.ts 文件功能相同,2 选 1 。.umirc.ts 文件优先级较高

  • dist:执行 umi build 后,产物默认会存放在这里。可通过配置修改产物输出路径

  • .env:环境变量,用户自己创建的

  • mock:存储 mock 文件,此目录下所有 jsts 文件会被解析为 mock 文件。用于本地的模拟数据服务。

  • public:此目录下所有文件会被 copy 到输出路径。

  • tsconfig.json:ts的配置文件

3、常用配置

3.1、typescript提示

如果想要在配置时也有 Typescript 的语法提示,可以在配置的地方包一层 defineConfig, 这样配置的时候就可以有语法提示了:

//umirc.ts
import {defineConfig} from 'umi'
export default defineConfig({
  npmClient: 'yarn',
});
3.2、常见配置设置
//umirc.ts
import {defineConfig} from 'umi'
export default defineConfig({
  npmClient: 'yarn',
  title:'Hello UMI4',//配置标题
  favicons:['/favicon.ico'],  //配置favicon使用本地图片,图片放在public目录下
});
3.2、环境变量配置

在项目根目录下的.env目录下配置,常见环境变量配置有修改服务器的端口号。

//.env
port=4000

三、路由配置

Umi 中关于路由的配置,有两种方式:

  • 配置式路由:在配置文件 .umirc.ts 中通过代码对路由进行相关的配置;

  • 约定式路由:不需要通过代码去手写路由配置,只需要按照 Umi 的约定去创建项目页面的目录,Umi 会自动解析出路由的配置;

在一个项目中,配置式路由和约定式路由只能任选其一。

1、配置式路由(掌握)

1.1、配置一二级路由

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

import { defineConfig } from 'umi';

export default defineConfig({
  routes: [
    { path: '/login', component: '@/pages/login'},
    { path:'/register',component:'@/pages/register'},
    {
      path: '/', component: '@/pages/index',
      routes: [
        { path: '/student', component: '@/pages/student'},
        { path: '/director', component: '@/pages/director' }
      ]
    }
  ]
});
1.2、配置路由出口

然后在 src/layouts/index 中通过 <Outlet/> 渲染子路由,配置一级路由出口

import {Outlet } from 'umi';
export default function Layout() {
  return (
    <div>
      <Outlet />
    </div>
  );
}

然后再在src/pages/index中配置二级路由的出口

import {Outlet} from 'umi'
import './index.less'
export default function index() {
  return (
    <div className='box'>
        <div className='navs'>
           <ul>
            <li>学生管理</li>
            <li>班主任管理</li>
           </ul>
        </div>
        <div className='main'>
          <Outlet></Outlet>
        </div>
    </div>
  )
}
1.3、配置路由模式

Umi 项目中,路由默认history 模式,如果要更改为 hash 模式,可以在配置文件 .umirc.ts 中添加以下属性:

export default defineConfig({    
    history: {
        type: 'hash'
    },
    // ...
});

2、路由跳转

Umi 中,将路由的跳转方式分为“声明式”和“命令式”,实际上对应的就是标签跳转和事件跳转。

2.1、声明式

通过<Link>组件方式进行跳转

import {Link, Outlet} from 'umi'
import './index.less'
export default function index() {
  return (
    <div className='box'>
        <div className='navs'>
           <ul>
            <li><Link to="/student">学生管理</Link></li>
            <li><Link to="/direct">班主任管理</Link></li>
           </ul>
        </div>
        <div className='main'>
          <Outlet></Outlet>
        </div>
    </div>
  )
}
2.2、命令式

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

import {history} from 'umi'
export default function login() {
  const toRegister=(e:any)=>{
    e.preventDefault()
    history.push('/register')
  }
  return (
    <div>
      <h1>登录</h1>
      <a href="#" onClick={toRegister}>没有账号,请注册</a>
    </div>
  )
}

3、路由传参

3.1、query传参
  • 跳转时传递参数

<Link to="/路径?参数名=参数值">跳转</Link>
history.push('/路径?参数名=参数值');
  • 组件中接收参数

import {useSearchParams} from 'umi'
const[searchParams,setSearchParams]=useSearchParams()
searchParams.get(参数名)
3.2、动态路由传参
  • 跳转时传递参数

history.push('/路径/参数')
  • 配置动态路由

.umirc.ts 文件中,更改动态路由的配置:

{ path: '/路径/:变量名', component: '组件路径' },
  • 在组件中获取参数

import { useParams } from 'umi';
const params = useParams();

4、路由的其他配置

4.1、路由重定向
[
    {
      path:'/',redirect:'/home'
    }
]
4.2、404页面配置

在umi中,只需要在所有路由配置的最后,添加一个关于404页面的配置

[
    {
      path:'*',
      component:'@/pages/notfound'
    }
]

四、Mock数据和网络请求

Mock数据是前后端开发过程中必不可少的一环,是前后端开发的关键链路,由于前后端开发过程中前端要使用到后端的数据,但是如果后端api没有开发出来,前端不会要等后端API才能开发,这样在开中会调职前端工作的阻塞,为了解决这个问题可以采用Mock数据的方式。

什么是 Mock 数据:在前后端约定好 API 接口以后,前端可以使用 Mock 数据来在本地模拟出 API 应该要返回的数据,这样一来前后端开发就可以同时进行,不会因为后端 API 还在开发而导致前端的工作被阻塞。

Umi 提供了开箱即用的 Mock 功能,能够用方便简单的方式来完成 Mock 数据的设置。

1、目录约定

Umi 约定 /mock 目录下的所有文件为 Mock 文件,例如这样的目录结构

.
├── mock
    ├── todos.js
    ├── items.js
    └── users.js
└── src
    └── pages
        └── index.js

2、Mock文件

Mock 文件默认导出一个对象,而对象的每个 Key 对应了一个 Mock 接口,值则是这个接口所对应的返回数据,例如这样的 Mock 文件:

export default{
    'GET /api/goods':[
        {id:'1001',name:'曲奇饼干',price:23.5},
        {id:'1002',name:'德芙巧克力',price:63.2},
        {id:'1003',name:'大列巴面包',price:13.5}
    ]
}

当 Http 的请求方法是 GET 时,可以省略方法部分,只需要路径即可

3、自定义函数

除了直接静态声明返回值,也可以用函数的方式来声明如何计算返回值

export default {
    'POST /api/login': (req, res) => {
        const { username, password } = req.body
        if (username == "Giles" && password == "123456") {
            res.send({
                code: 1,
                message: '登录成功'
            })
        } else {
            res.send({
                code: 0,
                message: '登录失败'
            })
        }
    }
}

4、引入Mock.js

在 Mock 中我们经常使用 Mock.js 来帮我们方便的生成随机的模拟数据,如果你使用了 Umi 的 Mock 功能,建议你搭配这个库来提升模拟数据的真实性:

首先在终端执行命令安装mockjs

yarn add mockjs

然后再在mock/citys.js目录下编写如下的代码,实现使用mockjs模拟mock数据

import mockjs from 'mockjs';
export default {
    'GET /api/tags': mockjs.mock({
        'list|100': [{ name: '@city', 'value|1-100': 50, 'type|0-2': 1 }],
    })
}

五、div状态机

1、dva状态机的工作流程

Umi 内置了 Dva 提供了一套状态管理方案:

2、Model配置

  • 在src目录下新建models文件夹,然后以购物车为例,在 src/models 目录中创建一个 shopcartModel.ts 文件

    src |--- models | |--- shopcartModel.ts
  • 配置dva

    首先要安装 @umijs/plugins

yarn add -D @umijs/plugins

然后需要在.umirc.ts配置文件中配置plugins和dva节点

// .umirc.ts
export default {
  npmClient: 'yarn',
  plugins: [
    '@umijs/plugins/dist/model',
    '@umijs/plugins/dist/dva',
  ],
  dva:{}
}

3、具体实现步骤

  • model的基本结构

    每一个仓库模块对象中,都有如下基本配置

const shopcartModel = {
    // 状态机模块名称(如果没有设置该属性,默认当前文件名为模块名)
    namespace: 'shopcart',
    // 数据
    state: {},
    // 修改数据的方法
    reducers: {},
    // 异步方法
    effects: {}
}
  • 设置数据初始化

const shopcartModel = {
    // 状态机模块名称(如果没有设置该属性,默认当前文件名为模块名)
    namespace: 'shopcart',
    // 数据
    state: {
        //定义初始数据
        rows:[]
    },
    // 修改数据的方法
    reducers: {},
    // 异步方法
    effects: {}
}
  • 设置修改数据的方法

const shopcartModel = {
    // 状态机模块名称(如果没有设置该属性,默认当前文件名为模块名)
    namespace: 'shopcart',
    // 数据
    state: {
        //定义初始数据
        rows:[]
    },
    // 修改数据的方法(同步的)
    reducers: {
       setShopcartList(state,{payload}){
           return{
            ...state,
            rows:payload
           }
        }
    },
    // 异步方法
    effects: {}
}
  • 设置异步方法

import $http from '../api/http'
const shopcartModel = {
    // 状态机模块名称(如果没有设置该属性,默认当前文件名为模块名)
    namespace: 'shopcart',
    // 数据
    state: {
        //定义初始数据
        rows:[]
    },
    // 修改数据的方法(同步的)
    reducers: {
        setShopcartList(state,{payload}){
            state.rows=payload.rows	
        }
    },
    // 异步方法
    effects: {
       *getShopcartListAsync({payload},{call,put}){
           const result=yield call($http.shopcartList.getShopcartList)
           yield put({type:'setShopcartList',payload:result.data.data})
        }
    }
}
export default shopcartModel

3、组件中使用操作仓库

使用之前需要安装react-redux包

yarn add react-redux
import {useEffect, useState} from 'react'
import {useSelector,useDispatch} from 'react-redux'
export default function student() {
  const dispatch=useDispatch()
  useEffect(()=>{
    dispatch({
      type:'shopcart/getShopcartListAsync'
    })
  },[])
  const list=useSelector((state)=>{
    return state.shopcart.rows
      
  })
  return (
    <div>
      <table>
        <thead>
          <tr>
            <td>编号</td>
            <td>名称</td>
            <td>价格</td>
            <td>数量</td>
            <td>小计</td>
          </tr>
        </thead>
        <tbody>
          {
            list.map(item=><tr key={item._id}>
              <td>{item._id}</td>
              <td>{item.name}</td>
              <td>{item.price}</td>
              <td>
                <button>-</button>
                {item.num}
                <button>+</button>
              </td>
              <td>{item.price*item.num}</td>
            </tr>)
          }
          </tbody>
      </table>
    
    </div>
  )
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/937817.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

运行命令出现错误 /bin/bash^M: bad interpreter: No such file or directory

在系统上运行一个 Linux 的命令的时候出现下面的错误信息&#xff1a; -bash: ./build.sh: /bin/bash^M: bad interpreter: No such file or directory 这个是在 Windows 作为 WSL 的时候出的错误。 原因和解决 出现问题的原因在于脚本在 Windows 中使用的回车换行和 Linux …

ANSYS软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 ANSYS是一款全球领先的工程仿真软件&#xff0c;广泛应用于机械、电气、流体、热力学等领域。它提供了强大的建模、网格划分、材料库、边界条件和载荷、求解器、结果后处理、批处理和脚本编程、多物理场仿真、协同设计和教育版等…

深入理解Android消息机制的原理

Handler & Looper & MessageQueue关系简述 一个线程至多有一个looper&#xff1b;一个looper有一个mq&#xff1b;一个mq对应多个message&#xff1b;一个message对应多个handler。消息类型&#xff1a;同步、异步、同步屏障消息。无限循环&#xff1a;在队列中没有消…

【C++从0到王者】第二十四站:多态的底层原理

文章目录 前言一、虚函数表二、一道经典的例题三、深度剖析多态的条件之一&#xff1a;为什么必须是父类的指针或引用四、深度剖析多态的条件之二&#xff1a;为什么是虚函数的重写/覆盖&#xff1f;五、虚函数表的一些总结六、关于Func3的验证七、动态绑定与静态绑定八、总结 …

数据分析作业2

中国在 2020 年开展第七次全国人口普查&#xff0c;截止 2021 年 5 月 11 日普查结果公布&#xff0c;全国人口共1411778724人。单从数据表格看相关数据不够直观&#xff0c;需要进行数据可视化展示&#xff0c;方便查看数据结果。 任务一&#xff1a;链接 MySQL 数据库&#x…

LeetCode 周赛上分之旅 #42 当 LeetCode 考树上倍增,出题的趋势在变化吗

⭐️ 本文已收录到 AndroidFamily&#xff0c;技术和职场问题&#xff0c;请关注公众号 [彭旭锐] 和 BaguTree Pro 知识星球提问。 学习数据结构与算法的关键在于掌握问题背后的算法思维框架&#xff0c;你的思考越抽象&#xff0c;它能覆盖的问题域就越广&#xff0c;理解难度…

webassembly003 ggml GGML Tensor Library part-2 官方使用说明

https://github.com/ggerganov/whisper.cpp/tree/1.0.3 GGML Tensor Library 官方有一个函数使用说明&#xff0c;但是从初始版本就没修改过 : https://github1s.com/ggerganov/ggml/blob/master/include/ggml/ggml.h#L3-L173 This documentation is still a work in progres…

【档案专题】七、电子档案利用与开发

导读&#xff1a;主要针对电子档案利用与开发相关内容介绍。对从事电子档案管理信息化的职业而言&#xff0c;不断夯实电子档案管理相关理论基础是十分重要。只有通过不断梳理相关知识体系和在实际工作当中应用实践&#xff0c;才能走出一条专业化加职业化的道路&#xff0c;从…

8.缓冲区管理

第五章 I/O管理 缓冲区管理 双缓冲区&#xff1a;T<CM 假设初始状态缓冲区1满&#xff0c;缓冲区2空&#xff0c;工作区为空。 刚开始缓冲区2为空&#xff0c;所以设备可以向缓冲区2中冲入数据耗时T&#xff0c;另一方面刚开始缓冲区1中是满的&#xff0c;所以刚开始就可…

免费OCR图像识别文字识别API

免费OCR图像识别文字识别API 一、OCR图像识别文字识别二、使用步骤1、接口2、请求参数3、请求参数示例4、接口 返回示例 三、温馨提示 一、OCR图像识别文字识别 光学字符识别&#xff08;Optical Character Recognition, OCR&#xff09;是指对文本资料的图像文件进行分析识别…

[管理与领导-55]:IT基层管理者 - 扩展技能 - 1 - 时间管理 -2- 自律与自身作则,管理者管好自己时间的五步法

前言&#xff1a; 管理好自己的时间&#xff0c;不仅仅是理念&#xff0c;也是方法和流程。 步骤1&#xff1a;理清各种待办事项 当提到工作事项时&#xff0c;这通常指的是要完成或处理的工作任务或事务。这些事项可以包括以下内容&#xff1a; 任务分配&#xff1a;根据工作…

2024年天津市大学软件学院专升本专业课考试大纲

天津市大学软件学院2024年“高职升本科”联合招生专业考试大纲 一、考试性质 天津市大学软件学院“高职升本科”联合招生专业考试是由合格的高职高专毕业生参加的选拔性考试。学校根据考生的成绩&#xff0c;按照已确定的招生计划&#xff0c;德、智、体全面衡量&#xff0c;…

fat32 文件系统 误删除文件数据恢复 SDK 介绍

fat32 文件系统 误删除文件数据恢复 SDK 介绍 fat32_analyze.dll 是一个专门用于恢复 fat32 文件系统误删除文件的标准的动态链接库(DLL)&#xff0c; 可被任何其他程序直接加载调用。 下载地址&#xff1a; https://gitee.com/tankaishuai/powerful_sdks/tree/master/fat32_a…

利用多种机器学习方法对爬取到的谷歌趋势某个关键词的每日搜索次数进行学习

大家好&#xff0c;我是带我去滑雪&#xff01; 前一期利用python爬取了谷歌趋势某个关键词的每日搜索次数&#xff0c;本期利用爬取的数据进行多种机器学习方法进行学习&#xff0c;其中方法包括&#xff1a;随机森林、XGBOOST、决策树、支持向量机、神经网络、K邻近等方法&am…

导入excel数据给前端Echarts实现中国地图-类似热力图可视化

导入excel数据给前端Echarts实现中国地图-类似热力图可视化 程序文件&#xff1a; XinqiDaily/frontUtils-showSomeDatabaseonMapAboutChina/finalproject xin麒/XinQiUtilsOrDemo - 码云 - 开源中国 (gitee.com) https://gitee.com/flowers-bloom-is-the-sea/XinQiUtilsOr…

第五章 树与二叉树 二、二叉树的定义和常考考点

一、定义 二叉树可以用以下方式详细定义&#xff1a; 二叉树是由节点构成的树形结构&#xff0c;每个节点最多可以有两个子节点。每个节点有以下几个属性&#xff1a; 值&#xff1a;存储该节点的数据。左子节点&#xff1a;有一个左子节点&#xff0c;如果没有则为空。右子节…

大数据(四)主流大数据技术

大数据&#xff08;四&#xff09;主流大数据技术 一、写在前面的话 To 那些被折磨打击的好女孩&#xff08;好男孩&#xff09;&#xff1a; 有些事情我们无法选择&#xff0c;也无法逃避伤害。 但请你在任何时候都记住&#xff1a; 你可能在一些人面前&#xff0c;一文不值&a…

基于内存池的 简单高效的数据库 SDK简介

基于内存池的 简单高效的数据库 SDK简介 下载地址&#xff1a; https://gitee.com/tankaishuai/powerful_sdks/tree/master/shm_alloc_db_heap shm_alloc_db_heap 是一个基于内存池实现的简单高效的文件型数据存储引擎&#xff0c;利用它可以轻松地像访问内存块一样读、写、增…

国产系统下开发QT程序总结

国产系统下开发QT程序总结 1. 国产系统简介 开发国产系统客户端的过程中&#xff0c;会出现兼容性问题。以下介绍Kylin和UOS环境下开发QT程序&#xff0c; 首先麒麟和统信这两个系统基于Ubuntu开发的。所以在Ubuntu开发理论上在国产系统上也能运行。芯片架构又分为amd,arm,mi…

谷歌翻译国内使用

谷歌已经退出中国市场&#xff0c;如果正常想使用的谷歌翻译的话&#xff0c;需要科学上网才可以 一些涉及到谷歌翻译的软件工具软件也无法正常使用&#xff0c;如chrome浏览器右键翻译&#xff0c;potplayer在线字幕实时翻译等等 目前最有效的解决方法就是通过修改hosts文件来…