ice/website/docs/guide/basic/router.md

159 lines
4.5 KiB
Markdown
Raw Normal View History

文档 (#203) * feat: docs directory * docs: 调整结构 * chore: lock * feat: update docs * docs: update assets doc * 新增文档 for 介绍 and 环境变量 (#307) * docs: add about * docs: add docs for env * docs: update about * docs: config (#306) * docs: router (#304) * docs: router * feat: getconfig * docs: get data * docs: ssg * docs: ssr * docs: document * docs: page * docs: enable ssr * fix: title * Doc/rax compat (#303) * docs: add docs of rax-compat * docs: modify doc of rax compat * Docs: app entry (#301) * docs: app entry * docs: app entry * docs: mock (#245) * docs: mock * chore: typo * chore: title * docs: styles (#244) * docs: style * chore: acss title * Docs: contributing (#243) * docs: contributing * chore: typo * chore: update contributing docs * fix: typo * chore: add putteteer install * docs: quick start (#235) * docs: quick start * chore: update IDE * chore: update docs * docs: app directory (#236) * docs: directory * chore: document desc * docs: update website * docs: update about * docs: update docs * chore: update prism * chore: update docs * chore: update Co-authored-by: luhc228 <luhengchang228@126.com> Co-authored-by: ClarkXia <xiawenwu41@gmail.com> Co-authored-by: 逆葵 <xianyong.yxy@alibaba-inc.com> Co-authored-by: ZeroLing <zhuoling.lcl@alibaba-inc.com> Co-authored-by: ZeroLing <i@zeroling.com> Co-authored-by: 水澜 <shuilan.cj@taobao.com> Co-authored-by: 染陌同学 <answershuto@gmail.com> Co-authored-by: luhc228 <44047106+luhc228@users.noreply.github.com>
2022-07-01 16:47:25 +08:00
---
title: 路由
order: 4
---
一个应用,通常包含多张页面,每张页面对应不同的地址。在 ICE 中,采用了约定式路由,会根据项目的目录结构自动生成应用的路由信息。
## 路由组件
路由组件,是每一个页面的入口文件,通过 `export default` 导出其具体实现,例如:
```tsx
// src/pages/index.tsx
export default function Home() {
return (
<div>Hello ICE</div>
);
};
```
更多能力,详见[页面](./page.md)。
## 路由规则
`src/pages` 目录下创建的每一个 `.(js|jsx|tsx)` 文件, 都对应着一个具体的路由。如下面的目录结构:
```
/src
└── pages
└── repo
| ├── index.tsx
| └── preview.tsx
├── about.tsx
└── index.tsx
```
对应的路由匹配规则为:
| URL | 路由组件 |
| --------------- |:--------------------------:|
| / | pages/index.tsx |
| /about | pages/about.tsx |
| /repo | pages/repo/index.tsx |
| /repo/preview | pages/repo/preview.tsx |
## 路由跳转
ice.js 通过 `Link` 组件,来提供路由间的跳转能力。基于 `Link` 组件,可以只加载下一个页面相比于当前页面差异化的 Bundle 进行渲染,以达到更好的性能体验。
文档 (#203) * feat: docs directory * docs: 调整结构 * chore: lock * feat: update docs * docs: update assets doc * 新增文档 for 介绍 and 环境变量 (#307) * docs: add about * docs: add docs for env * docs: update about * docs: config (#306) * docs: router (#304) * docs: router * feat: getconfig * docs: get data * docs: ssg * docs: ssr * docs: document * docs: page * docs: enable ssr * fix: title * Doc/rax compat (#303) * docs: add docs of rax-compat * docs: modify doc of rax compat * Docs: app entry (#301) * docs: app entry * docs: app entry * docs: mock (#245) * docs: mock * chore: typo * chore: title * docs: styles (#244) * docs: style * chore: acss title * Docs: contributing (#243) * docs: contributing * chore: typo * chore: update contributing docs * fix: typo * chore: add putteteer install * docs: quick start (#235) * docs: quick start * chore: update IDE * chore: update docs * docs: app directory (#236) * docs: directory * chore: document desc * docs: update website * docs: update about * docs: update docs * chore: update prism * chore: update docs * chore: update Co-authored-by: luhc228 <luhengchang228@126.com> Co-authored-by: ClarkXia <xiawenwu41@gmail.com> Co-authored-by: 逆葵 <xianyong.yxy@alibaba-inc.com> Co-authored-by: ZeroLing <zhuoling.lcl@alibaba-inc.com> Co-authored-by: ZeroLing <i@zeroling.com> Co-authored-by: 水澜 <shuilan.cj@taobao.com> Co-authored-by: 染陌同学 <answershuto@gmail.com> Co-authored-by: luhc228 <44047106+luhc228@users.noreply.github.com>
2022-07-01 16:47:25 +08:00
```jsx
// src/pages/index.tsx
import { Link } from 'ice';
export default function Home() {
return (
<>
<div>Hello ICE</div>
<Link to="/about">about ice</Link>
</>
);
}
```
## 布局组件
`pages` 目录下,还可以创建一类特殊的组件,来维护全局或一组页面共用的布局, 其文件名约定为 `layout.(js|jsx|tsx)`
布局组件和路由组件一样,也通过 `export default` 导出其具体实现。
```jsx
import { Outlet } from 'ice';
export default function Layout() {
return (
<div>
<h1>Root Layout</h1>
<h2>Hello ICE</h2>
<Outlet />
</div>
)
}
```
其中, `<Outlet />` 组件对应需要被布局组件嵌套的子组件。
布局组件:
- 如果位于 `pages` 目录的最顶层,则它将作为全局布局,嵌套在所有路由组件外。
- 如果位于某个子文件夹,则它将作为页面级布局,嵌套在这个目录下的其他路由组件外。
如果同时存在 **全局布局组件****页面级布局组件**,则全局布局组件会嵌套于页面级布局组件之外。
例如,下面的目录结构:
```diff
/src
├── layout.tsx
└── pages
└── repo
+ | ├── layout.tsx 页面级布局组件
| ├── index.tsx
| └── preview.tsx
├── about.tsx
+ ├── layout.tsx 全局布局组件
└── index.tsx
```
每个路由,对应的 Layout 匹配规则为:
| URL | 路由组件 | 布局组件 |
| --------------- |:--------------------------:|-------------------------------------------:|
| / | pages/index.tsx | src/layout.tsx |
| /about | pages/about.tsx | src/layout.tsx |
| /repo | pages/repo/index.tsx | src/layout.tsx + src/pages/repo/layout.tsx |
| /repo/preview | pages/repo/preview.tsx | src/layout.tsx + src/pages/repo/layout.tsx |
## 动态路由
路由中包含了动态参数的路由,被称做动态路由。如果文件名或者目录名是以 `$` 开头,则判定这个路由为动态路由。
> 注意:动态路由仅在 SSR 下生效。
例如,下面的目录结构:
```diff
/src
├── layout.tsx
└── pages
└── repo
+ ├── $id
+ | ├── author
+ | | └── $name.tsx
+ | └── index.tsx
├── index.tsx
└── preview.tsx
```
对应的路由匹配规则为:
| URL | 路由组件 |
|----------------------|:--------------------------:|
| /repo | pages/repo/index.tsx |
| /repo/preview | pages/repo/preview.tsx |
| /repo/ice | src/pages/repo/$id/index.tsx |
| /repo/ice/author/foo | src/pages/repo/$id/author/$name.tsx |
在动态路由组件中可以通过 `useParams()` 方法拿到当前路由的参数:
```tsx
// src/pages/repo/$id/author/$name.tsx
import { useParams } from 'ice';
export default function() {
const { id, name } = useParams();
console.log(id); // 'ice'
console.log(name); // 'foo'
return <div />;
}
```