UmiJS基础+UmiUI安装使用+Mock使用示例+DvaJS案例
title: UmiJS基础
date: 2022-09-12 19:20:27
tags:
- React
- 框架
- UmiJS
categories: - 框架
UmiJS
介绍
-
可扩展
Umi 实现了完整的生命周期,并使其插件化,Umi 内部功能也全由插件完成。此外还支持插件和插件集,以满足功能和垂直域的分层需求。
-
开箱即用
Umi 内置了路由、构建、部署、测试等,仅需一个依赖即可上手开发。并且还提供针对 React 的集成插件集,内涵丰富的功能,可满足日常 80% 的开发需求。
-
企业级
经蚂蚁内部 3000+ 项目以及阿里、优酷、网易、飞猪、口碑等公司项目的验证,值得信赖。
-
大量自研
包含微前端、组件打包、文档工具、请求库、hooks 库、数据流等,满足日常项目的周边需求。
-
完备路由
同时支持配置式路由和约定式路由,同时保持功能的完备性,比如动态路由、嵌套路由、权限路由等等。
-
面向未来
在满足需求的同时,我们也不会停止对新技术的探索。比如 modern mode、webpack@5、自动化 external、bundler less 等等。
快速上手
安装
创建空目录
kdir myapp && cd myapp
使用官方提供脚手架
yarn create @umijs/umi-app
安装依赖
yarn start
部署发布-----打包好的文件生成在dist文件下
yarn build
项目目录
- .editorconfig // 对编辑器的默认配置
- .gitignore // git忽略文件配置
- .prettierignore // 代码格式化忽略的文件
- .prettierrc // 代码格式化的配置
- .umirc.ts // umijs核心配置文件
- package.json // 依赖管理
- README.md // 项目介绍
- tsconfig.json // ts配置文件
- typings.d.ts // ts类型文件
配置
Umi 在 .umirc.ts
或 config/config.ts
中配置项目和插件,支持 es6。一份常见的配置如下官方配置文档
export default {
base: '/docs/',
publicPath: '/static/',
hash: true,
history: {
type: 'hash',
},
}
路由配置
routes: [
{
path: '/',
component:'@/pages/index', // 路由模板
title:'首页'
},
{
path:'/list',
redirect:'user/one' // 重定向
},
{
path:'/user',
component:'@/layouts/index', // 公共路由模板,子路由也会在其中通过{props.children}
routes:[
{path:'/user/one',component:'@/pages/index'},
{path:'/user/two',component:'@/pages/user'}
]
}
],
// jsx部分,公共路由模板,存放进layouts文件下
return (
<div>
<h1>Header</h1>
{props.children}
<h1>Footer</h1>
</div>
)
拦截
路由跳转可以进行拦截操作,当要跳转的时候拦截跳转至另一个组件
{
path:'/user',
component:'@/layouts/index', // 公共路由模板,子路由也会在其中通过{props.children}
wrappers:[
'@/wrappers/auth' // 拦截路由
],
routes:[
{path:'/user/one',component:'@/pages/index'},
{path:'/user/two',component:'@/pages/user'}
]
}
// wrappers/auth.jsx
import React from 'react';
import { Redirect } from 'umi';
const auth = (props:any) => {
const isLoadin = false;
if (isLoadin) { // 这部分功能可以实现当登陆状态为false强制跳转到首页
return <div>{props.children}</div>
}else{
return <Redirect to="/"/>
}
}
export default auth
未知路径
当路径查找不到,可以设置默认路径
routes: [
{
path: '/',
component:'@/pages/index', // 路由模板
title:'首页'
},
{
path:'/list',
redirect:'user/one' // 重定向
},
{
path:'/user',
component:'@/layouts/index', // 公共路由模板,子路由也会在其中通过{props.children}
wrappers:[
'@/wrappers/auth'
],
routes:[
{path:'/user/one',component:'@/pages/index'},
{path:'/user/two',component:'@/pages/user'},
{component:'@/pages/404'} // 当查找不到上方路径的时候,页面就会跳转到该组件路径
]
},
{component:'@/pages/404'}// 当查找不到上方路径的时候,页面就会跳转到该组件路径
],
传递参数
{ path:'/user/one/:id?',component:'@/pages/index' },
以上都是配置式路由,而如果没有routes配置,则自动进入约定式路由,跟Next的page路由规则类似。src下的文件目录就是路由表,
Mock数据
新建文件mock/index.ts
export default {
// 请求+路径
'GET /api/index':{
id:1,
name:'Tom',
age:12
},
'GET /api/person':{
id:2,
name:'LiLi',
age:22
},
}
获取数据
// 点击触发的函数
const getData = async()=>{
// 请求数据
// 1.写法一
// request('/api/index').then(res=>{
// console.log(res);
// })
// 2.写法二
const data = await request('/api/person');
console.log(data);
}
Mockjs使用
官方文档:Mockjs文档
import mockjs from 'mockjs'; // 引入第三方库mockjs
export default {
'GET /api/index':{
id:1,
name:'Tom',
age:12
},
'GET /api/person':{
id:2,
name:'LiLi',
age:22
},
'GET /api/tags':mockjs.mock({
'list|100': [{ name: '@city', 'value|1-100': 50, 'type|0-2': 1 }],
})
}
关闭Mock
- 打开文件
\Umijs\.umirc.ts
,修改配置文件:
import { defineConfig } from 'umi';
export default defineConfig({
...
mock:false, // 关闭mock
...
});
- 使用环境变量方式关闭
"scripts": {
...
"start:nomock":"MOCK=none umi dev",
...
},
配合DvaJS
新建\pages\dva.tsx
组件
// 1.创建一个UI组件
// 2.创建 model
// 3.将UI组件和model进行链接
import React from 'react';
import { connect } from 'umi';
import { Button } from 'antd';
const dva = (props) => {
console.log(props);
const {dispatch} = props;
const getData = ()=>{
// 使用model更新获取数据
dispatch({
type:'tags/fetchTags', // model的命名空间 / 方法
payload:null
})
}
return (
<div>
<h1>Dva组件</h1>
<Button onClick={getData}>获取列表数据</Button>
</div>
)
}
export default connect(( {tags} )=>({tags}))(dva);
新建\src\models\tags.ts
文件
import { request } from "umi"
// 获取标签数据
const getTags = ()=>{
return request('/api/tags')
}
export default {
// 效用model的时候,通过命名空间调用,不要和其他model同名
namespace: 'tags',
// 状态,跟react中的state类似,和redux中保存的state一样
state: {
tagsList:[]
},
// 调用服务端接口,获取数据
effects: {
// payload:UI调用model传递的参数
// callback:回调函数,执行其他操作就可以使用这个回调函数
// put:将数据传递给reducers
// call:访问外部的方法
*fetchTags({payload,callback},{put,call}){
// 获取tags数据
const response = yield call(getTags)
// 调用reducers,传递数据
yield put({
type:'setTagList', // 类似于redux中action的type
payload:response
})
}
},
// 更新 state
reducers: {
setTagList(state,action){
return {...state,tagsList:action.payload}
}
},
}
运行时配置
runtime-config 和 config 之间的区别在于执行时间,runtime-config 是在您的应用程序在浏览器中运行时评估的。因此,
function
可以使用jsx
、import
和其他浏览器可运行的片段。
新建文件src/app.tsx
代码示例(不代表所有功能):
import {history} from 'umi';
// 定义额外路由变量
let extraRoutes;
// 动态添加路由
export function patchRoutes({ routes, routeComponents }) {
console.log('patchRoutes', routes, routeComponents);
routes.unshift({
path:'/foo',
component:require('@/pages/user1').default
})
// 合并服务端返回的路由
extraRoutes.map(item=>{
routes.unshift({
path:item.path,
component:require(`@/pages${item.component}`).default
})
})
}
// 复写 render 会在patchRoutes之前执行
export function render(oldRender) {
// 模拟从服务端请求获得的 路由
extraRoutes = [
{
path:'/server',
component:'/user2'
}
]
// 在渲染之前 进行权限校验
const isLoading = true; // 模拟 登录/未登录 状态
if(!isLoading){
history.push('/login')
}
oldRender();
}
// 在初始加载和路由切换时做一些事情,在patchRoutes之后执行
export function onRouteChange({ location, clientRoutes, routes, action }) {
console.log(location,'01');
console.log(clientRoutes,'02');
console.log(routes,'03');
console.log(action,'04');
// console.log(location.pathname);
}
使用Umi UI
安装:
yarn add @umijs/preset-ui -D
启动:
yarn start