Day12 - Astro Series: Routes

Astro 系列文第十二日:基础路由

一个漂亮的渐变背景上面有一句标题:「基础路由」

前言

在上一章节介绍了基础组件的使用,并且你也大概猜到了,只要组件放置在 src/pages/ 之内就会自动的成为 Astro 的页面,在本章节会更细致的介绍关于 Astro 的路由设置。

页面路由

Astro 采用的路由策略被称为「基于文件的路由 File-based Routing」,所以可以透过整理 pages 内文件夹的结构来设置页面。以下是支持的文件种类:

  • .astro
  • .md
  • .mdx
  • .html
  • .js / .ts

静态路由

每一个在 pages 中的文件都会成为对应的页面,如下:

Terminal window
# 例:静态路由
src/pages/index.astro -> mysite.com/
src/pages/about.astro -> mysite.com/about
src/pages/about/index.astro -> mysite.com/about
src/pages/about/me.astro -> mysite.com/about/me
src/pages/posts/1.md -> mysite.com/posts/1

动态路由(SSG 模式)

单纯的静态路由可以满足大多数构建网页的需求,但有时候会希望依照资料来创建对应的页面,而非一个一个手动创建,这时候就是「动态路由」登场的时机,动态路由根据渲染模式,会有两种不同的撰写方式(SSG、SSR),本教学先着重介绍静态生产页面之模式。

举例来说目前博客有上百篇文章,不太可能特地为每一篇都创建一个页面来生成路由,这么做不但耗时也难以统一修改,但如果透过动态路由就可以根据资料来自动创建全新的路由。

由于在 SSG 模式下在构建时需要事先确定所有的路由,因此在动态路由组件中必须回传一个 getStaticPaths 方法🔗,这个方法回传一个数组中夹带着对象,对象中夹带 params 属性,并且可以选择性地添加 props 属性。

---
export async function getStaticPaths() {
return [
{ params: { /* 必要 */ }, props: { /* 选择性添加 */ } },
{ params: { ... } },
{ params: { ... } },
// ...
];
}
---

至于组件文件的名称便是参数,回传的 params 当中必须要有这个参数作为属性。举例来说:src/pages/authors/[author] 这个动态组件内可以这样写:

---
export async function getStaticPaths() {
return [
{ params: { author: 'mike' } },
{ params: { author: 'joe' } },
{ params: { author: 'mary' } },
// ...
];
}
const { author } = Astro.params;
---
<h1>这里是 { author } 的页面</h1>

就成功地生成三个页面: /authors/mike/authors/joe/authors/mary 每个页面中显示对应的作者名称,就完成最简单的动态路由了,接着可以更进一步将资料抽离出来,使用 map 方法组成需要回传的数组:

// 第一步:在 pages/authors 资料夹内创建 [author].astro
---
export async function getStaticPaths() {
// 第二步:定义页面资料
const pages = [
{
slug: 'mike',
author: "Mike",
description: "设计师",
},
{
slug: "joe",
author: "Joe",
description: "后端工程师",
},
{
slug: "mary",
author: "Mary",
description: "前端工程师",
},
];
// 第三步:使用 map 来组成 getStaticPaths 所要求的回传格式
return pages.map(({ slug, author, description}) => {
return {
params: { author: slug },
props: { author, description },
};
});
}
// 第四步:在页面中获得传入的 Props 并解构出来
const { author, description } = Astro.props;
---
// 第五步:在模板中显示
作者: {author} - {description}

如此一来就成功地在 pages/authors 文件夹中创建了三位作者的页面,并且显示对应的数据。在这个示例中仍然是使用事先定义在组件中的数据 pages,在未来章节中将会学到如何整合 CMS 或使用 Astro 内建的 Content Collection 来引入 .md 或 .mdx 文件。

剩余参数

如果需要更为灵活的页面路径可以尝试使用剩余参数 [...path] 在 .astro 文件名称上来匹配任何深度的路径,举例来说以下动态路由 pages/sequences/[...path].astro 将会产生三个页面:

  1. /sequences/one/two/three
  2. /sequences/four
  3. /sequences

如果将参数设置为 undefined 则会匹配成顶级页面,在这个案例中是 /sequences

---
export function getStaticPaths() {
return [
{params: {path: 'one/two/three'}},
{params: {path: 'four'}},
{params: {path: undefined }}
]
}
---

其他补充

404 页面

如果要构建 404 错误页面只需要在 /src/pages 里面创建 404.astro404.md 即可。

排除页面

Terminal window
src/pages/
├── _hidden-directory/
├── page1.md
└── page2.md
├── _hidden-page.astro
├── index.astro
└── posts/
├── _SomeComponent.astro
├── _utils.js
└── post1.md

如果希望暂时禁用页面可以在文件名称添加下划线 _ 来避免该页面被构建,像是以上例子只有 post1.mdindex.astro 会被渲染出来。

总结

在本章节介绍了如何创建 Astro 页面,主要着重在 SSG 模式下静态与动态路由如何构建,以及分页与其他琐碎的小功能介绍。

最后建议实际动手练习:

延伸阅读