动态加载组件。
常见使用场景:组件体积太大,不适合直接计入 bundle 中,以免影响首屏加载速度。例如:某组件 HugeA 包含巨大的实现 / 依赖了巨大的三方库,且该组件 HugeA 的使用不在首屏显示范围内,可被单独拆出。这时候,dynamic
就该上场了。
为什么使用 dynamic
:封装了使用一个异步组件需要做的状态维护工作,开发者可以更专注于自己的业务组件开发,而不必关心 code spliting、async module loading 等等技术细节。
通常搭配 动态 import 语法 使用。
封装一个异步组件
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 />;}
可用于获取当前路由信息,
import { history } from 'umi';// history 栈里的实体个数console.log(history.length);// 当前 history 跳转的 action,有 PUSH、REPLACE 和 POP 三种类型console.log(history.action);// location 对象,包含 pathname、search 和 hashconsole.log(history.location.pathname);console.log(history.location.search);console.log(history.location.hash);
可用于路由跳转,
import { history } from 'umi';// 跳转到指定路由history.push('/list');// 带参数跳转到指定路由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();
主要在插件利用,项目代码中一般用不到。
运行时插件接口,是 Umi 内置的跑在浏览器里的一套插件体系。
比如:
import { plugin, ApplyPluginsType } from 'umi';// 注册插件plugin.register({apply: { dva: { foo: 1 } },path: 'foo',});plugin.register({apply: { dva: { bar: 1 } },path: 'bar',});// 执行插件// 得到 { foo: 1, bar: 1 }plugin.applyPlugins({key: 'dva',type: ApplyPluginsType.modify,initialValue: {},args: {},async: false,});
参数属性包含:
主要在插件利用,项目代码中一般用不到。
运行时插件执行类型,enum 类型,包含三个属性:
链接组件,例如:
import { Link } from 'umi';export default () => {return (<div>{/* 点击跳转到指定 /about 路由 */}<Link to="/about">About</Link>{/* 点击跳转到指定 /courses 路由,附带 query { sort: 'name' }*/}<Link to="/courses?sort=name">Courses</Link>{/* 点击跳转到指定 /list 路由,附带 query: { sort: 'name' }附带 hash: 'the-hash'附带 state: { fromDashboard: true }*/}<Linkto={{pathname: "/list",search: "?sort=name",hash: "#the-hash",state: { fromDashboard: true },}}>List</Link>{/* 点击跳转到指定 /profile 路由,附带所有当前 location 上的参数*/}<Linkto={location => {return { ...location, pathname: "/profile" };}}/>{/* 点击跳转到指定 /courses 路由,但会替换当前 history stack 中的记录*/}<Link to="/courses" replace />{/*innerRef 允许你获取基础组件(这里应该就是 a 标签或者 null)*/}<Linkto="/courses"innerRef={node => {// `node` refers to the mounted DOM element// or null when unmounted}}/></div>);};
特殊版本的 <Link />
。当指定路由(to=指定路由
)命中时,可以附着特定样式。
import { NavLink } from 'umi';export default () => {return (<div>{/* 和 Link 等价 */}<NavLink to="/about">About</NavLink>{/* 当前路由为 /faq 时,附着 class selected */}<NavLink to="/faq" activeClassName="selected">FAQs</NavLink>{/* 当前路由为 /faq 时,附着 style */}<NavLinkto="/faq"activeStyle={{fontWeight: "bold",color: "red",}}>FAQs</NavLink>{/* 当前路由完全匹配为 /profile 时,附着 class */}<NavLink exact to="/profile" activeClassName="selected">Profile</NavLink>{/* 当前路由为 /profile/ 时,附着 class */}<NavLink strict to="/profile/" activeClassName="selected">Profile</NavLink>{/* 当前路由为 /profile,并且 query 包含 name 时,附着 class */}<NavLinkto="/profile"exactactiveClassName="selected"isActive={(match, location) => {if (!match) {return false;}return location.search.includes("name");}}>Profile</NavLink></div>);};
提供一个用户离开页面时的提示选择。
import { Prompt } from 'umi';export default () => {return (<div>{/* 用户离开页面时提示一个选择 */}<Prompt message="你确定要离开么?" />{/* 用户要跳转到首页时,提示一个选择 */}<Promptmessage={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><ul><li>history: {history.action}</li><li>location: {location.pathname}</li><li>match: {`${match.isExact}`}</li></ul></div>);});
hooks,获取 history
对象
import { useHistory } from "umi";export default () => {const history = useHistory()return (<div><ul><li>history: {history.action}</li></ul></div>);};
hooks,获取 location
对象
import { useLocation } from "umi";export default () => {const location = useLocation()return (<div><ul><li>location: {location.pathname}</li></ul></div>);};
hooks,获取 params
对象。 params
对象为动态路由(例如:/users/:id
)里的参数键值对。
import { useParams } from "umi";export default () => {const params = useParams()return (<div><ul><li>params: {JSON.stringify(params)}</li></ul></div>);};
获取当前路由的匹配信息。
import { useRouteMatch } from "umi";export default () => {const match = useRouteMatch()return (<div><ul><li>match: {JSON.stringify(match.params)}</li></ul></div>);};
通过 package.json 的 main 字段露出,且不存在于 modules 字段里。
Umi 内核的 Service 方法,用于测试,或调用 Umi 底层命令。
utils 方法,给插件使用,和插件里的 api.utils 是同一个底层库。
用于校验和提示用户配置类型,详见配置#TypeScript 提示。