Astro を学んでみる(6)

本記事は、書籍「Astro フロントエンド開発の教科書」によるAstroの勉強、6回目です。

記事内のコードは書籍のものではなく、独自に作成しています。

第5章 コンポーネントベースのWebサイト制作

5.1 コンポーネントベースのWebサイト制作ケーススタディの概要

架空の企業Webサイトを制作していきたいと思います。

作成するページ

ページ名URLファイル名
TOPページ/index.astro
企業概要ページ/aboutabout.astro
ニュース一覧ページ/newsnews/[...page].astro
ニュース詳細ページ/news/news-1news/news-[id].astro

作成するファイル

種別内容ファイル名
layoutsTOPページのレイアウトTopLayout.astro
layouts下層ページのレイアウトLowerLayout.astro
componentsヘッダーコンポーネントHeader.astro
componentsフッターコンポーネントFooter.astro
componentsニュースコンポーネントNewsListItem.astro
componentsカードコンポーネントCard.astro
tsインターフェースの定義ファイルinterface.ts
tsお知らせ情報管理ファイルnewsList.ts
jsonお知らせ情報の中身newsData.json
---
---

<header>
    <h1>
        <a href="/">株式会社XXX</a>
    </h1>
    <nav>
        <ul>
            <li><a href="/about/">企業概要</a></li>
            <li><a href="/news/">ニュース一覧</a></li>
        </ul>
    </nav>
</header>

<style>
    header {
        display: flex;
        justify-content: space-between;
        align-items: center;
    }
    nav ul {
        list-style: none;
        display: flex;
        gap: 1em;
    }
</style>

ナビゲーションは別ファイルとして作った方が良かったですが、とりあえずここに直書きさせています。

左上に表示させている会社名はロゴが入る予定の箇所です。

---
---

<footer>
    <address>
        <p>株式会社XXX</p>
        <p>〒012-3456</p>
        <p>東京都YYY区ZZZ町1-1-1</p>
    </address>

    <p class="copyright">©株式会社XXX</p>
</footer>

<style>
    footer {
        text-align: center;
        background-color: #ccc;
        padding: 10px 0;
    }
    .copyright {
        font-size: 0.7em;
        margin-top: 50px;
    }
</style>

フッターについては特に何もありません。

5.2 BaseLayoutの作成

TOPページ用と、下層ページ用の2種類を作成しました。

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

interface Props {
	title: string
}
const {title} = Astro.props;
---
<!doctype html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width" />
		<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
		<meta name="generator" content={Astro.generator} />
		<title>株式会社XXX | {title}</title>
	</head>
	<body>
		<Header />
		<main>
			<slot />
		</main>
		<Footer />
	</body>
</html>

<style>
	body {
		margin: 0 auto;
		padding: 20px;
    	max-width: 1200px;
	    height: auto;
	}
</style>

TOPページ用のレイアウトでは、HTML基本構造を作り、ヘッダーとフッターをコンポーネントで呼び出しています。

中身の部分はindex.astroにまかせます。

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

interface Props {
	title: string
}
const {title} = Astro.props;
---
<!doctype html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width" />
		<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
		<meta name="generator" content={Astro.generator} />
		<title>株式会社XXX | {title}</title>
	</head>
	<body>
		<Header />
		<main>
			<section class="lowerHeader">
				<h2>{title}</h2>
				<div class="content">
					<slot />
				</div>
			</section>
		</main>
		<Footer />
	</body>
</html>

<style>
	body {
		margin: 0 auto;
		padding: 20px;
    	max-width: 1200px;
	    height: auto;
	}
	
    .lowerHeader h2 {
        text-align: center;
        line-height: 3em;
        border-top: 1px solid #000;
        border-bottom: 1px solid #000;
    }
    .content {
        margin: 50px 100px;
    }
</style>

下層ページ用のレイアウトは、TOPページ用と異なりmainタグの中身を少し記述しています。タイトルは下層ページ共通の予定ですので、このようにしました。コンテンツ部分については各ページファイルに任せます。

なお、bodyタグのCSSが2つのファイルで被っていますので、本来cssファイルに別出しするべきですね。

5.3 TOPページの作成

---
import TopLayout from "@/layouts/TopLayout.astro";
import Card from "@/components/Card.astro";

import NewsListItem from "@/components/NewsListItem.astro";
import newsList from "@/content/newsData.json";

const title: string = "トップページ";
---

<TopLayout title = {title}>
	<section class="mainVisual">
		<p>メインヴィジュアル</p>
	</section>
	<section class="newsArea">
		<h2>ニュース一覧</h2>
		
		<ul>
			{
				newsList.map(
					(item) => (
						<NewsListItem 
							news={item} 
						/>
					)
				)
			}
		</ul>
	</section>
	<section class="cardArea">
		<h2>ご案内</h2>
		<Card />
	</section>
</TopLayout>

<style>
	section:not(:first-child) {
		margin-top: 50px;
	}
	.mainVisual {
		width: 100%;
		height: 300px;
		background-color: aqua;
		display: flex;
		justify-content: center;
		align-items: center;
	}
	h2 {
		text-align: center;
	}
	.mainVisual p {
		font-size: 3em;
	}
	.cardArea {
		width: 90%;
		margin: 20px auto;
	}
</style>

TOPページのコンテンツ部分です。

メインビジュアルには画像表示やスライダー表示を想定しています。

お知らせについては、日付やカテゴリーも出したいところです。

ご案内の部分については、カードを並べています。特に見せたいページなどを紹介する事を想定しています。

---
---
<div class="cardList">
<dl>
    <dt></dt>
    <dd>テキストテキスト</dd>
</dl>
<dl>
    <dt></dt>
    <dd>テキスト2テキスト2</dd>
</dl>
<dl>
    <dt></dt>
    <dd>テキスト3テキスト3</dd>
</dl>
</div>

<style>
    .cardList {
        display: flex;
        justify-content: space-around;
    }
    dl dt {
        width: 200px;
        height: 200px;
        background-color: antiquewhite;
    }
    dl dd {
        text-align: center;
        margin: 10px;
    }
</style>

Cardコンポーネントのdtタグには画像を表示する想定です。

5.4 ニュースページとマークダウンファイル

ニュースについては、これまでに作成したファイルを代用しています。

5.5 デプロイの準備

最終的に出来上がったサイトは下記となります。

TOPページ

企業概要ページ

ニュース一覧ページ

ニュース詳細ページ

\ 最新情報をチェック /

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA