🚀Astroをコンポーネントに分けて構築する方法

イントロダクション

この記事は前回からの続きとなっているので、Astroの構築から調べたい方はこちらの記事をご覧ください。

この記事では、Astroをコンポーネントに分解して構築する方法について説明します。

コンポーネントの分割

Astroでは、コンポーネント(要素)ごとにファイルを分割することができ、これにより再利用可能でメンテナンスしやすいコードを書くことができます。コンポーネントは、それぞれ.astroファイルで作成して、import文を使って呼び出します。

コンポーネントの例

シンプルな例ですが、これを分けてみます。

---
---

<html lang="ja">
	<head>
		<meta charset="utf-8" />
		<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
		<meta name="viewport" content="width=device-width" />
		<meta name="generator" content={Astro.generator} />
		<title>Astro</title>
	</head>
	<body>
		<header>
			<h2>ヘッダーのリスト</h2>
			<nav>
				<ul>
					<li><a href="">HOME</a></li>
					<li><a href="">ABOUT</a></li>
					<li><a href="">CONTACT</a></li>
				</ul>
			</nav>
		</header>
		<main>
			<h1>Astro demo</h1>
			<p>Astroのデモページです。</p>
		</main>
		<footer>
			<h2>フッターのリンク</h2>
			<ul>
				<li><a href="">HOME</a></li>
				<li><a href="">ABOUT</a></li>
				<li><a href="">CONTACT</a></li>
			</ul>
		</footer>
	</body>
</html>
index.astro

とりあえずhead,header,footerに分けたあと、headerとfooterのul,li要素が共通になっているので、これもコンポーネント化してみます。

フォルダ構成

まずsrcフォルダの配下にcomponentsフォルダを作成して、そこにコンポーネントのファイルを格納します。ここでは

image block

index.astroから該当部分をカットして、貼り付けします。

---

---
<head>
  <meta charset="utf-8" />
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
  <meta name="viewport" content="width=device-width" />
  <meta name="generator" content={Astro.generator} />
  <title>Astro</title>
</head>
Head.astro

---

---
<header>
  <nav>
    <ul>
      <li><a href="">HOME</a></li>
      <li><a href="">ABOUT</a></li>
      <li><a href="">CONTACT</a></li>
    </ul>
  </nav>
</header>
Header.astro

---

---
<footer>
  <h2>フッターのリンク</h2>
  <ul>
    <li><a href="">HOME</a></li>
    <li><a href="">ABOUT</a></li>
    <li><a href="">CONTACT</a></li>
  </ul>
</footer>
Footer.astro

ファイルの読み込みは---区切られたコードフェンス内でimportして、呼び出したい箇所にコンポーネントを記載します。

---
import Head from "../components/Head.astro";
import Header from "../components/Header.astro";
import Footer from "../components/Footer.astro";
---

<html lang="ja">
	<Head />
	<body>
		<Header />
		<main>
			<h1>Astro demo</h1>
			<p>Astroのデモページです。</p>
		</main>
		<Footer />
	</body>
</html>
index.astro

コンポーネントの一文字目は大文字で記載しておくとHTMLのタグとの見分けがつきやすいです。また、<Head />のように閉じタグは不要ですが、最後に/がつくので忘れないようにしましょう。

コンポーネントで分ける前とブラウザの表示が変わらなければOKです。

あとはHeaderコンポーネントとFooterコンポーネントにあるリストをコンポーネント化しつつ、ループ処理で書いてみます。

componentsフォルダにMenuList.astroというファイルを作ります。

---

---
<ul>
  <li><a href="">HOME</a></li>
  <li><a href="">ABOUT</a></li>
  <li><a href="">CONTACT</a></li>
</ul>
MenuList.astro

次にHeaderコンポーネントとFooterコンポーネントで読み込みます。

---
import MenuList from "./MenuList.astro"
---
<header>
  <nav>
    <MenuList />
  </nav>
</header>
Header.astro

---
import MenuList from "./MenuList.astro"
---
<footer>
  <h2>フッターのリンク</h2>
  <MenuList />
</footer>
Footer.astro

これをimportで読み込んでも変わらず表示されますが、ページ数が増えても編集がしやすいようli要素をループで表示させてみます。ループ処理にはmapを使用します。

---
const items= [
  { href: "/", page: "Home" },
  { href: "/about", page: "About" },
  { href: "/contact", page: "Contact" },
];
---
<ul>
  {items.map(item => (
    <li>
      <a href={item.href}>
        {item.page}
      </a>
    </li>
  ))}
</ul>
MenuList.astro

コードフェンス内で定義した変数はファイル内で呼び出すことができます。mapを使う場合には{}の間で記述する必要があるので、注意です。

まとめ

これでコンポーネント化ができました。共通要素をコンポーネント化することで編集や再利用性の高い構築ができていくかと思います。
次の記事でCSSでのスタイリングの例を紹介していこうと思います。