约定式路由
前言
umi对于路由的处理,主要通过两种方式:
- 约定式路由:使用约定好的文件夹和文件,来代表页面,umi会根据开发者书写的页面来生成路由配置
- 配置式路由:直接书写配置文件
一、约定式路由具体的约定
-
umi约定,工程中的pages文件夹存放的是页面,如果工程中包含src目录,则src/pages文件夹下存放的是页面。
-
umi约定,页面的文件名,以及该页面的路径,是浏览器匹配的路径。
-
umi约定,如果pages文件夹下的文件是index.js,则可以省略文件名(注意避免文件名和当前目录的文件夹名称相同)。
-
umi约定,如果src/layouts目录存在,则该目录下的index.js表示的全局通用的布局,布局中的children则添加具体的页面。
-
umi约定,如果子目录下需要自己通用的布局,则在子目录下加上_layout.js文件,则子目录下面的页面以及下级目录都会通用该布局
-
404约定,umi约定,pages/404.js表示404页面,如果无匹配路由,则会渲染该页面,该约定再开发模式无效,只有部署之后生效。
-
约定 [ ] 包裹的文件或文件夹为动态可选路由。(src/pages/users/[id ] . t s x 会 成 为 / u s e r s / : i d ? 或 者 s r c / p a g e s / u s e r s / [ i d ].tsx 会成为 /users/:id? 或者src/pages/users/[id ].tsx会成为/users/:id?或者src/pages/users/[id]/settings.tsx 会成为 /users/:id?/settings)
import React from 'react'
import { useParams} from 'umi'
export default function $id() {
const params = useParams();
return (
<div>
<h1>{params.id}</h1>
</div>
)
}
二、路由跳转
- 跳转链接: Link NvaLink
import React from 'react'
import { Link, NavLink} from 'umi'
export default function index(props) {
return (
<div>
<div>
<Link to="/" style={{ marginLeft: "10px" }}>首页</Link>
<Link to="/page1" style={{ marginLeft: "10px" }}>page1</Link>
<NavLink to="/page2" style={{ marginLeft: "10px" }}>page2</NavLink>
<NavLink to="/sub/subPage1" style={{ marginLeft: "10px" }}>subPage1</NavLink>
</div>
{props.children}
<div><h1>页脚</h1></div>
</div>
)
}
- 代码跳转:WithRouter组件
import React from 'react'
import {withRouter } from 'umi'
export default function index(props) {
console.log(props)
return (
<div>
<div>
<button onClick={() => {
props.history.push("/page1");
}}>跳转到page1</button>
<button onClick={() => {
props.history.push("/sub/subPage1");
}}>跳转到subpage1</button>
</div>
{props.children}
<div><h1>页脚</h1></div>
</div>
)
}
三.路由的信息获取
- 所有的页面,布局组件,都会通过属性获取到下面的属性
1.match:等同于react-router的match
import { useHistory } from 'umi';
export default () => {
const history = useHistory();
return (
<div>
<ul>
<li>history: {history.action}</li>
</ul>
</div>
);
};
2.history:等同于react-router的history(特殊之处在于,history.location.query被封装成了一个对象,使用的是query-string库来进行封装的)
import { useHistory } from 'umi';
export default () => {
const history = useHistory();
return (
<div>
<ul>
<li>history: {history.action}</li>
</ul>
</div>
);
};
3.location:等同于react-router的location
import { useLocation } from 'umi';
export default () => {
const location = useLocation();
return (
<div>
<ul>
<li>location: {location.pathname}</li>
</ul>
</div>
);
};
4.route:对应的路由信息
- 如果需要在普通组件获取路由信息,可以使用高阶组件WithRouter进行封装
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>
);
});
配置式路由
- Umi 在 .umirc.ts 或 config/config.ts 中配置项目和插件,支持 es6。一份常见的配置如下
export default {
base: '/docs/',
publicPath: '/static/',
hash: true,
history: {
type: 'hash',
},
}
- 如果项目的配置不复杂,推荐在 .umirc.ts 中写配置; 如果项目的配置比较复杂,可以将配置写在 config/config.ts 中,并把配置的一部分拆分出去,比如路由配置可以拆分成单独的 routes.ts:
// config/routes.ts
export default [
{ exact: true, path: '/', component: 'index' },
];
// config/config.ts
import { defineConfig } from 'umi';
import routes from './routes';
export default defineConfig({
routes: routes,
});