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

4.5 KiB

title order
路由 4

一个应用,通常包含多张页面,每张页面对应不同的地址。在 ICE 中,采用了约定式路由,会根据项目的目录结构自动生成应用的路由信息。

路由组件

路由组件,是每一个页面的入口文件,通过 export default 导出其具体实现,例如:

// src/pages/index.tsx
export default function Home() {
  return (
    <div>Hello ICE</div>
  );
};

更多能力,详见页面

路由规则

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 通过 Link 组件,来提供路由间的跳转能力。基于 Link 组件,可以只加载下一个页面相比于当前页面差异化的 Bundle 进行渲染,以达到更好的性能体验。

// 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 导出其具体实现。

import { Outlet } from 'ice';

export default function Layout() {
  return (
  	<div>
      <h1>Root Layout</h1>
      <h2>Hello ICE</h2>
      <Outlet />
    </div>
  )
}

其中, <Outlet /> 组件对应需要被布局组件嵌套的子组件。

布局组件:

  • 如果位于 pages 目录的最顶层,则它将作为全局布局,嵌套在所有路由组件外。
  • 如果位于某个子文件夹,则它将作为页面级布局,嵌套在这个目录下的其他路由组件外。

如果同时存在 全局布局组件页面级布局组件,则全局布局组件会嵌套于页面级布局组件之外。

例如,下面的目录结构:

/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 下生效。

例如,下面的目录结构:

/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() 方法拿到当前路由的参数:

// 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 />;
}