Umi 是蚂蚁金服的底层前端框架,是可扩展的企业级前端应用框架。Umi 以路由为基础的,同时支持配置式路由和约定式路由,保证路由的功能完备,并以此进行功能扩展。然后配以生命周期完善的插件体系,覆盖从源码到构建产物的每个生命周期,支持各种功能扩展和业务需求。
// 先查看是否安装了node,确保node版本是8.10及以上。
node -v
// 使用yarn全局安装umi
yarn global add umi
// 创建项目
mkdir umiAppDemo
// 进入项目文件夹
cd umiAppDemo
// 创建页面
umi g page index
// 启动项目
umi dev
// build打包,会创建一个dist文件
umi build
使用场景:组件体积太大,不适合直接计入 bundle 中,以免影响首屏加载速度。例如:某组件 HugeA 包含巨大的实现 / 依赖了巨大的三方库,且该组件 HugeA 的使用不在首屏显示范围内,可被单独拆出。这时候我们可以更专注于自己的业务组件开发,而不必关心 code spliting、async module loading 等等技术细节。
import { dynamic } from 'umi';
export default dynamic({
loader: async function () {
// 这里的注释 webpackChunkName 可以指导 webpack 将该组件 HugeA 以这个名字单独拆出去
const { default: HugeA } = await import(
/* webpackChunkName: "external_A" */ './HugeA'
);
return HugeA;
},
});
// 使用
import React from 'react';
import AsyncHugeA from './AsyncHugeA';
// 像使用普通组件一样即可
// dynamic 为你做:
// 1. 异步加载该模块的 bundle
// 2. 加载期间 显示 loading(可定制)
// 3. 异步组件加载完毕后,显示异步组件
export default () => {
return <AsyncHugeA />;
};
这里路由与react路由基本一样分为链接组件和特定样式组件
<div>
{/* 点击跳转到指定 /home 路由 */}
<Link to="/home">home</Link>
{/* 点击跳转到指定 /home 路由,携带参数*/}
<Link to="/home?sort=name">home</Link>
{/* 点击跳转到指定 /home 路由,
附带 query: { sort: 'name' }
附带 hash: 'the-hash'
附带 state: { fromDashboard: true }
*/}
<Link
to={{
pathname: '/home',
search: '?sort=name',
hash: '#the-hash',
state: { fromDashboard: true },
}}
>
home
</Link>
{/* 点击跳转到指定 /profile 路由,附带所有当前 location 上的参数*/}
<Link to={(location) => { ...location, pathname: '/profile' }} />
{/* 点击跳转到指定 /home 路由,但会替换当前 history stack 中的记录 */}
<Link to="/home" replace />
{/* innerRef 允许你获取基础组件(这里应该就是 a 标签或者 null) */}
<Link
to="/courses"
innerRef={(node) => {
<a>home</a>
}}
/>
</div>
特殊版本的 。当指定路由(
to=指定路由
)命中时,可以附着特定样式。
<div>
{/* 和 Link 等价 */}
<NavLink to="/home">home</NavLink>
{/* 当前路由为 /home 时,附着 class selected */}
<NavLink to="/home" activeClassName="selected">
home
</NavLink>
{/* 当前路由为 /home 时,附着 style */}
<NavLink
to="/home"
activeStyle={{
fontWeight: 'bold',
color: 'red',
}}
>home</NavLink>
{/* 当前路由完全匹配为 /home 时,exact代表强校验路由包含斜杠 */}
<NavLink exact to="/home" activeClassName="selected">
home
</NavLink>
{/* 当前路由为 /home/ 时,strict代表包强校验如果没有斜杠校验不通过*/}
<NavLink strict to="/home/" activeClassName="selected">
home
</NavLink>
{/* 当前路由为 /home,并且 query 包含 name 时,附着 class */}
<NavLink
to="/home"
exact
activeClassName="selected"
isActive={(match, location) => {
if (!match) {
return false;
}
return location.search.includes('name');
}}
>
Profile
</NavLink>
</div>
引入umi中的history对象,使用内部配置的方法,可以获取路由信息、路由跳转等操作;
import { history } from 'umi';
// history 栈里的实体个数
console.log(history.length);
// 当前 history 跳转的 action,有 PUSH、REPLACE 和 POP 三种类型
const {action} = history;
// location 对象,包含 pathname、search 和 hash
const {pathname,search,hash} = history.location;
import { history } from 'umi';
// 跳转到指定路由
history.push('/home');
// 带参数跳转到指定路由
history.push('/list?a=b');
history.push({
pathname: '/list',
query: {
a: 'b',
},
});
// 跳转到上一个路由
history.goBack();
import { history } from 'umi';
const unlisten = history.listen((location, action) => {
console.log(location.pathname);
});
unlisten();
import { Prompt } from 'umi';
export default () => {
return (
<div>
{/* 用户离开页面时提示一个选择 */}
<Prompt message="你确定要离开么?" />
{/* 用户要跳转到首页时,提示一个选择 */}
<Prompt
message={(location) => {
return location.pathname !== '/' ? true : `您确定要跳转到首页么?`;
}}
/>
{/* 根据一个状态来确定用户离开页面时是否给一个提示选择 */}
<Prompt when={formIsHalfFilledOut} message="您确定半途而废么?" />
</div>
);
};
可以通过 withRouter
获取到 history
、location
、match
对象
import { withRouter } from 'umi';
export default withRouter(({ history, location, match }) => {
return (
<div>{history.action}-{location.pathname}-{`${match.isExact}`}
</div>
);
});
history
对象import { useHistory } from 'umi';
const history = useHistory();
location
对象import { useLocation } from 'umi';
const location = useLocation();
params
对象。 params
对象为动态路由(例如:/users/:id
)里的参数键值对import { useParams } from 'umi';
const params = useParams();
umi框架扩展性非常强,支持各种功能扩展和业务需求,不在局限于选择vue框架或是react框架;
大量自研,包含微前端、组件打包、文档工具、请求库、hooks 库、数据流等,满足日常项目的周边需求;
创建项目快,不用像创建react项目一样需要配置typescript/less/css modules;
uni框架很多配置都是约定规则,照约定好的方式开发,就能达到某种效果,中间的过程由框架帮我们完成。这使得灵活性降低,但是规范性增强了;详细配置