umi
开始
使用yarn创建项目
yarn create @umijs/umi-app
安装依赖
yarn
运行项目
yarn start
umi目录结构
.
├── package.json--依赖文件
├── .umirc.ts--配置文件
├── .env--环境变量
├── dist--打包文件夹
├── mock--mockjs存放的文件夹
├── public--此目录的文件会被coty到输出路径
└── src
├── .umi--临时文件目录,比如入口文件、路由等这个目录不要提交,因为运行或者打包时会自动生成
├── layouts/index.tsx--全局布局文件
├── pages--路由组件
├── index.less--index页面样式
└── index.tsx--首页
└── app.ts--运行时的配置
package.json
:包含插件和插件集,以 @umijs/preset-、@umijs/plugin-、umi-preset- 和 umi-plugin- 开头的依赖会被自动注册为插件或插件集
.umirc.ts
:包含umi内置功能和插件的配置
.env
:环境变量
dist
:打包存放的文件夹
mock
:mockjs存放的文件夹
public
:此目录的文件会被coty到输出路径
.umi
:临时文件目录,比如入口文件、路由等这个目录不要提交,因为运行或者打包时会自动生成
layouts/index.tsx
:全局布局文件
index.less
:index页面样式
index.tsx
:首页
app.ts
:运行时配置文件
路由配置
在umi中,应用都是单页面应用,页面地址的跳转都是在浏览器端完成的
配置路由
.umirc.ts
文件中的routes配置
routes: [
{ path: '/', component: '@/pages/index' },
],
path
: 路径通配符
component
:React组件,如果指向src
目录下的文件可以用@
exact
:表示是否严格匹配
例如:
//home123 匹配失败
{exact:true, path: '/home', component: '@/pages/home' }
//home123 匹配成功
{exact:false, path: '/home', component: '@/pages/home' }
//home123 匹配失败
{path: '/home', component: '@/pages/home' }
默认去匹配不了 ,umi官方的文档目前还是v2的目前umi最新版3.2.22
所以有些东西官方文档还没有更新,不信各位看官可以去试试
redirect
:配置路由跳转
访问/
跳转到/index
{path: '/', redirect:'/index' },
子路由配置
例如:配置user
下的两个子路由
{
path: '/user',
component: '@/pages/user/index',
routes:[
{path:'/user/login', component:'@/pages/user/login'},
{path:'/user/register', component:'@/pages/user/register'}
]
},
在配置子路由的时候需要注意在父级路由
写上props.children
函数写法
export default (props) => {
return <div style={{ padding: 20 }}>{ props.children }</div>;
}
类写法
import React, {Component} from 'react';
class Index extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
index
{this.props.children}
</div>
)
}
}
export default Index
路由级权限校验
路由鉴权,就是当你访问一个路由的时候会判断你是否有这个权限访问如果没有则跳转,有则显示。
经常应用在判断用户是否登录
在umi中使用wrappers []
来判断
例如以下例子:
访问/user 首先进入user/auth
判断权利
{
path: '/user',
component: '@/pages/user/index',
wrappers: [
'@/pages/user/auth',
],
routes:[
{path:'/user/login', component:'@/pages/user/login'},
{path:'/user/register', component:'@/pages/user/register'}
]
},
auth
文件代码这里我条件先设为true 如果真则实现组件否则跳转到user/login
登录这就是路由鉴权
import React from 'react';
const { Redirect } = require('dva').router;
export default (props) => {
const isLogin = true;
if (isLogin) {
return <div>{ props.children }</div>;
} else {
return <Redirect to="/user/login" />
}
}
umi中js跳转
在umi使用js跳转需要从umi
引入history对象
import React, {Component} from 'react';
import { history } from 'umi'
class Index extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
//普通跳转
history.push('/index')
//带参跳转 参数page 值为1
history.push('/index?page=1')
//另一种带参写法
history.push({
pathname:'/index',
query:{
page:1
}
})
}
render() {
return (
<div>
index
{this.props.children}
</div>
)
}
}
export default Index
约定式路由
umi也支持约定式路由但是必须避免
以下规则,否则将不会被注册为路由
- 以 . 或 _ 开头的文件或目录
- 以 d.ts 结尾的类型定义文件
- 以 test.ts、spec.ts、e2e.ts 结尾的测试文件(适用于 .js、.jsx 和 .tsx 文件)
- components 和 component 目录
- utils 和 util 目录
- 不是 .js、.jsx、.ts 或 .tsx 文件
- 文件内容不包含 JSX 元素
使用约定式路由
比如保证在.umirc.ts
文件中没有设置routes
,如果设置routes
约定式路由不能使用
例如当前目录会被解释如下
动态路由
约定[]
包裹的文件或者文件夹为动态路由
文件用[]
包裹,路由的设置
地址栏:
这里的张三就作为参数传递,从this.props.match.params
中获取参数
这样会匹配到的路经是
http://localhost:8000/level/zhagnsan //匹配 http://localhost:8000/level/zhagnsan/123 //不匹配 http://localhost:8000/level/ //不匹配
全局组件
应用场景:网页导航栏我们经常希望所有的页面都显示,此时就会用到全局组件
在src
下新建的一个组件
在.umirc.ts
里设置路由,可以看到这里pages
下的页面其实都是子路由,这样就可以保证所有页面都有layout/index
这个页面
routes:[
{
path:'/', component: '@/layout/index',
routes:[
{path:'/',component: '@/pages/index.tsx'},
{path:'/home',component: '@/pages/home.tsx'},
{path:'/user',component: '@/pages/user/index.tsx'},
{path:'/user/login',component: '@/pages/user/login.tsx'},
{path:'/user/register',component: '@/pages/user/register.tsx'},
{path:'/user/auth',component: '@/pages/user/auth.tsx'},
{path:'/level',component: '@/pages/level/index.tsx'},
{path:'/level/:id',component:'@/pages/level/[name].tsx'}
]
}
]
另外layout/index
的代码如下
import { IRouteComponentProps } from 'umi'
import React from 'react';
export default function Layout({ children, location, route, history, match }: IRouteComponentProps) {
return (
<div>
layoutIndex
{children}
</div>
)
}
插件
插件的id和key
每个插件都会有一个id和key,id是路径的缩写,key是进一步简化配置的唯一值
例如:
在umi中插件无序注册,umi会自动注册
在umi3.0前配置插件的方式在.umirc.ts
中配置
plugins: [
['umi-plugin-react', {
dva: {},
antd: {},
...
}]
],
3.0以后的配置方式
"antd": {},
“dva”: {}
查看使用的插件
umi plugin list //列出所有的插件
umi plugin list --key //列出所有插件的key
禁用插件
在.umirc.ts
文件中用key
设置为false
页面跳转
umi中跳转方式有两个一种声明式
和命令式
声明式:
通过Link来实现跳转和react-router中的使用一样
import { Link, History } from 'umi'
export default () => {
return (
<div>
<h1 className={styles.title}>Page index</h1>
<Link to={'/level'}>level</Link>
</div>
);
}
命令式:
通过使用history进行跳转
import { history } from 'umi';
function goToListPage() {
history.push('/list');
}
mock数据
约定式mock在mock
文件下编写的文件会被解析为mock文件
关闭 mock
.umirc.ts文件
中设置
export default {
mock: false,
};
引入mockJS模拟数据
import mockjs from 'mockjs';
export default {
// 使用 mockjs 等三方库
'GET /api/tags': mockjs.mock({
'list|100': [{ name: '@city', 'value|1-100': 50, 'type|0-2': 1 }],
}),
};
设置环境变量
设置运行端口
# OS X, Linux
PORT=3000 umi dev
# Windows (cmd.exe)
set PORT=3000&&umi dev
如果要同时考虑 OS X 和 Windows,可借助三方工具 cross-env,
yarn add cross-env --dev
cross-env PORT=3000 umi dev
另外可以在根目录下创建.env
文件进行配置
这里配置了端口为3000,并且禁止babel的缓存
APP_ROOT:指定项目根目录,APP_ROOT不能再.env中
配置,只能再命令行配置
ANALYZE:用于分析bundle构成,默认关闭
ANALYZE=1 umi dev
或者
ANALYZE=1 umi build
ANALYZE_SSR:对服务端包大小的分析,默认关闭
BABEL_CACHE:默认开启 Babel 编译缓存,值为 none 时禁用缓存。
BABEL_POLYFILL:默认会根据 targets 配置打目标浏览器的全量补丁,设置为 none 禁用内置的补丁方案。
COMPRESS:默认压缩 CSS 和 JS,值为 none 时不压缩,build 时有效。
FORK_TS_CHECKER:默认不开启 TypeScript 类型检查,值为 1 时启用。
FORK_TS_CHECKER=1 umi dev
FRIENDLY_ERROR:设为 none 时禁用,有些场景下 friendly-errors-webpack-plugin 会把错误给吞了。
FRIENDLY_ERROR=none umi dev
HTTPS:localhost 开启 https
HTTPS=1 umi dev
同时也可以使用配置 https: { key: ‘/path/key.pem’, cert: ‘/path/cert.pem’ } 自定义证书。
HMR:设为 none 时禁用代码热更新功能。
HTML:设为 none 时不输出 HTML,umi build 时有效。
HOST:默认是 0.0.0.0。
PORT:指定端口号,默认是 8000
PROGRESS:设为 none 时禁用进度条
PROGRESS=none umi dev
SOCKET_SERVER:
指定用于 HMR 的 socket 服务器
**SPEED_MEASURE:**分析 Webpack 编译时间,支持 CONSOLE 和 JSON 两种格式,默认是 JSON
SPEED_MEASURE=CONSOLE umi dev
TERSER_CACHE:默认开启 Terser 压缩缓存,值为 none 时禁用缓存
样式
再umi中约定src/global.css
为全局样式,如果存在此文件,会被引用到入口文件最前面
图片
再js中使用图片要通过require()
引用相对路径的图片
按需加载
在umi中使用dynamic
实现按需加载,此功能默认关闭需要在.umirc.ts
文件中开启
export default {
dynamicImport: {},
}
首先对需要按需加载的组件进行封装
import { dynamic } from 'umi';
export default dynamic({
loader: async function() {
// 这里的注释 webpackChunkName 可以指导 webpack 将该组件 HugeA 以这个名字单独拆出去
const { default: HugeA } = await import(/* webpackChunkName: "external_A" */ './huge');
return HugeA;
},
});
封装完使用和普通组件一样进行引用即可
import React from 'react';
import AsyncHugeA from './AsyncHugeA';
// 像使用普通组件一样即可
// dynamic 为你做:
// 1. 异步加载该模块的 bundle
// 2. 加载期间 显示 loading(可定制)
// 3. 异步组件加载完毕后,显示异步组件
export default () => {
return <AsyncHugeA />;
}