ice/docs/guide/basic/router.md

221 lines
5.8 KiB
Markdown
Raw Normal View History

2020-05-09 19:09:14 +08:00
---
2020-10-28 16:19:57 +08:00
title: 路由配置
2020-05-09 19:09:14 +08:00
order: 3
---
2020-11-03 12:29:03 +08:00
icejs 推荐使用 **配置式路由** 进行应用的路由管理,如果希望使用约定式路由可参考 [文档](/docs/guide/advance/convention-routing)。
2020-07-08 21:08:00 +08:00
## 配置路由信息
2020-05-09 19:09:14 +08:00
应用的路由信息统一在 `src/routes.ts` 中配置,配置协议支持多级嵌套,具体如下:
2020-05-09 19:09:14 +08:00
```ts
import UserLayout from '@/Layouts/UserLayout';
import UserLogin from '@/pages/UserLogin';
import NotFound from '@/components/NotFound';
import wrapperPage from '@/components/WrapperPage';
2020-05-09 19:09:14 +08:00
const routerConfig = [
// 分组路由children 里的路由会将父节点的 component 作为布局组件
{
path: '/user',
component: UserLayout,
children: [
{
2020-08-17 10:39:45 +08:00
// 路由路径
2020-05-09 19:09:14 +08:00
path: '/login',
2020-08-17 10:39:45 +08:00
// 精确匹配
2020-05-09 19:09:14 +08:00
exact: true,
2020-08-17 10:39:45 +08:00
// 路由组件
2020-05-09 19:09:14 +08:00
component: UserLogin,
// 配置路由的高阶组件
wrappers: [wrapperPage]
2020-05-09 19:09:14 +08:00
},
{
path: '/',
// 重定向
redirect: '/user/login',
},
{
// 404 没有匹配到的路由
component: NotFound,
},
],
},
// 非分组路由
{
path: '/about',
component: About,
},
];
export default routerConfig;
```
> 注意:路由有一个按顺序匹配的规则,从上到下一旦命中路由匹配规则就会停止遍历,因此如果你在最前面配置了 / 这样一个路由,则所有的路由都会命中该规则,导致其他路由没有效果,所以在开发时要注意路由的顺序以及 exact 属性的使用。
2020-11-03 12:29:03 +08:00
## 运行时配置
`src/app.ts` 中,我们可以配置路由的类型和基础路径等信息,具体配置如下:
2020-11-03 12:29:03 +08:00
```jsx
import { runApp } from 'ice';
const appConfig = {
router: {
type: 'browser',
basename: '/seller',
fallback: <div>loading...</div>
modifyRoutes: (routes) => {
return routes;
}
}
};
runApp(appConfig);
```
**options**:
- type: 路由类型,默认值 `hash`,可选值 `browser|hash|static`
- basename: 路由基准地址
- fallback: 开启按需加载时配置 fallback UI
- modifyRoutes: 动态修改路由
- history: 自定义创建 history 对象,[详见](https://github.com/ReactTraining/history/blob/master/docs/GettingStarted.md)
## 路由组件参数
对于路由组件(即页面级组件),可通过 `props` 获取到如下属性:
- `location`:当前路由的 location 对象,包含 `pathname`、`search`、`hash`、`state` 属性
- `history`:详见 [history api](/docs/guide/basic/api#history)
- `searchParams`:当前 URL 的查询参数对象(需要开启 [parseSearchParams](/docs/guide/basic/app#启动项配置)
- `match`:当前路由和 URL match 后的对象,包含 `path`、`url`、`params`、`isExact` 属性
对于非路由组件,组件内如想获取上述属性需要借助 [withRouter](/docs/guide/basic/api#withRouter) API。
2020-05-09 19:09:14 +08:00
## 路由跳转
- React 组件内部:使用 [Link 组件](/docs/guide/basic/api#Link) 或 [useHistory](/docs/guide/basic/api#useHistory) API
- 非 React 组件内部:使用 [history API](/docs/guide/basic/api#history)
## 按需加载
参考 [代码分割](/docs/guide/advance/code-splitting) 。
## 路由高阶组件
通过 `src/routes.ts` 中的 `wrappers` 字段可配置路由的高阶组件,常用于路由级别的权限检验。
#### 配置 wrappers
```diff
+import WrapperPage from '@/components/WrapperPage';
const routerConfig = [
{
path: '/user',
component: User,
// 配置路由的高阶组件
+ wrappers: [WrapperPage]
},
]
```
Release (#3811) * feat: support uniqueName of plugin-icestark (#3804) * feat: support uniqueName of plugin-icestark * chore: version * fix: update userconfig * fix: ci error * chore: optimize code * fix: update userconfig (#3829) * fix: update userconfig * fix: ci error * chore: optimize code * fix: component name with dash code in store config (#3824) * fix: returns html with UNICODE when Chinese words are passed in ssr (#3819) * fix: ssr html decode error * fix: ssr html decode error * fix: cheerio decodeEntities config * fix: package version * fix: typo mpa (#3826) * chore: formate yml * fix: compatible with undefined options (#3828) * fix: compatible with undefined options * chore: version * feat: inner plugin ice auth (#3805) * feat: inner build-plugin-ice-auth * feat: compatible with adding plugin * fix: comment * refactor: mpa config (#3825) * refactor: remove inline loader of entry * fix: format path in win * fix: mpa entries * fix: mpa config * fix: default src dir when use mpa * fix: compatible with files do not export component * feat: support wrappers of Layout component (#3822) * feat: support wrappers of Layout * fix: wrapper router * chore: remove useless code * refactor: motify userconfig * chore: revert minify file * chore: optimize code * feat: support off eslint * feat: support framework custom cli options (#3838) * feat: support framework custom cli options * chore: rename config * feat: update review * fix: compatible with build-mpa-config * fix: default config output dir (#3847) * fix: same instance of task config (#3848) * feat: ssr fallback (#3837) * feat: support ssr fallback * feat: support csr get ctx * chore: getInitialContext func * fix: location undefined * chore: remove package.json * chore: remove useless code * fix: format * fix: state * fix: comment * fix: lint warning * fix: lint warning * fix: ci * docs: update notice of wrappers (#3849) * chore: version (#3834) * chore: version * chore: plugin-mpa version * chore: versions * chore: plugin-store version * chore: version * chore: version Co-authored-by: fushen <fushen.jzw@alibaba-inc.com> Co-authored-by: Hengchang Lu <44047106+luhc228@users.noreply.github.com> Co-authored-by: William <wiolem@hotmail.com> Co-authored-by: yangfan <18767120422@163.com>
2020-11-23 14:53:22 +08:00
> 注意Wrapper 组件不支持通过 lazy 导入
#### 实现高阶组件
```tsx
// src/components/LoginWrapper
import { useAuth, Redirect } from 'ice';
const LoginWrapper = (WrappedComponent) => {
2020-11-26 21:14:24 +08:00
const Wrapped = (props) => {
const [auth] = useAuth();
return (
<>
{
2020-11-26 21:14:24 +08:00
auth.isLogin ? <WrappedComponent {...props} /> : <Redirect to="/login" />
}
</>
)
};
return Wrapped;
}
export default LoginWrapper;
```
通过 `wrappers` 配置我们可以对路由组件进行自定义包装,如上示例通过 WrapperPage 高阶组件对路由组件进行权限判断,如果是登录状态,则渲染 User 组件,否则跳转到 `/login` 路由。
> `useAuth` API 需要结合 plugin-ice-auth 插件实现,可参考 [权限管理](/docs/guide/advance/auth) 。
2020-05-09 19:09:14 +08:00
## 常见问题
### HashHistory 与 BrowserHistory
前端路由通常有两种实现方式HashHistory 和 BrowserHistory路由都带着 `#` 说明使用的是 HashHistory。这两种方式优缺点
| 特点\\方案 | HashRouter | BrowserRouter |
| --- | --- | --- |
| 美观度 | 不好,有 # 号 | 好 |
| 易用性 | 简单 | 中等,需要 server 配合 |
| 依赖 server | 不依赖 | 依赖 |
| 跟锚点功能冲突 | 冲突 | 不冲突 |
| 兼容性 | IE8 | IE10 |
开发者可以根据自己的实际情况选择对应方案。
### 如何使用 BrowserRouter
本地开发时,只需要在 `src/app.ts` 中增加以下配置即可:
```diff
2020-10-20 14:04:37 +08:00
import { runApp } from 'ice';
2020-05-09 19:09:14 +08:00
const appConfig = {
router: {
+ type: 'browser',
}
};
2020-10-20 14:04:37 +08:00
runApp(appConfig);
2020-05-09 19:09:14 +08:00
```
线上运行时需要服务端支持,否则会出现刷新 404 问题,具体方案请参考社区文档:
- [关于 react-router 的 browserHistory 模式](https://github.com/LoeiFy/Recordum/issues/15)
- [react-router 之 HashRouter & BrowserRouter](https://zzugbb.github.io/passages/react-router%E9%97%AE%E9%A2%98/)
### 如何使用动态路由
在某些场景下可能需要动态指定路由即 `/user/:id`,使用方式如下:
路由配置:
```ts
import UserInfo from '@/pages/UserInfo';
// src/routes.ts
const routerConfig = [
{
path: '/user/:id',
exact: true,
component: UserInfo,
}
]
```
动态路由参数:
```tsx
import { useParams } from 'ice';
export default = () => {
const { id } = useParams();
// console.log(id) // 123
}
```