Astroが最近流行りつつありますね。
個人的にも非常に注目していまして、これから沢山使っていきたいと思っている技術です。
軽く触ってみた感じ、Vue・React経験がある方はスムーズに取得できるのではないかと思っています。
今回はコンポーネントに値を渡す方法についてご紹介します。
🎴 Cardコンポーネントを作成(子)
[ src/components/AppCard.astro ]を作成していください。
作成後、以下の記述追記。
---
interface Props {
id:string
image:string
title:string
text:string
alt:string
}
const { id,image,title,text,alt} = Astro.props;
---
<article id={id} class="app-card">
<div class="app-card__image">
<img src={image} alt={alt}>
</div>
<div class="app-card__inner">
<h2 class="app-card__title">{ title }</h2>
<p class="app-card__text">{ text }</p>
</div>
</article>
※今回はスタイリング部分は省略します。
分割してみていきましょう。
まずは、型定義部分です。
interface Props {
id:string
image:string
title:string
text:string
alt:string
}
特に変わったところはありませんね。
そして、props部分です。
const { id,image,title,text,alt} = Astro.props;
公式サイトで以下の様な説明があります。
propsは、フロントマタースクリプトのグローバルな Astro.props で利用できます。
propsを使いたい時はこの書き方で書けば問題なさそうですね。
公式曰く「分割代入になるから注意してくださいね」とのこと。
次に、マークアップ部分です。
<article id={id} class="app-card">
<div class="app-card__image">
<img src={image} alt={alt}>
</div>
<div class="app-card__inner">
<h2 class="app-card__title">{ title }</h2>
<p class="app-card__text">{ text }</p>
</div>
</article>
こちらも特に変わったところはありませんね。
propsで受け取った値を表示しています。
🔖 index.astroについて(親)
親コンポーネント側の記述についてです。
こちらでは、表示したいテキスト類を配列で定義してmapでループしています。
---
import Layout from '../layouts/Layout.astro';
import AppCard from '../components/AppCard.astro';
import image01 from "@/assets/image01.jpg";
import image02 from "@/assets/image02.jpg";
import image03 from "@/assets/image03.jpg";
const cards = [
{
id:"01",
image:image01,
title:"タイトル01",
text:"テキストテキストテキストテキスト",
alt:"image01"
},
{
id:"02",
image:image02,
title:"タイトル02",
text:"テキストテキストテキストテキスト",
alt:"image02"
},
{
id:"03",
image:image03,
title:"タイトル03",
text:"テキストテキストテキストテキスト",
alt:"image03"
},
]
---
<Layout title="Astro Props">
<main id="main" class="l-main">
<div class="flex">
{cards.map(card =>(
<AppCard
id={card.id}
image={card.image}
alt={card.alt}
title={card.title}
text={card.text}
/>
))}
</div>
</main>
</Layout>
Cardコンポーネントをインポートして読み込み、配列で定義した値を渡しています。
今回は、3つオブジェクトを定義しているので以下のmapによって3回ループが行われます。
{cards.map(card =>(
<AppCard
id={card.id}
image={card.image}
alt={card.alt}
title={card.title}
text={card.text}
/>
))}
最終的にスタイリングも含めて行うと以下の様な表示になります。
💭改行を入れたい場合
set:html というものが用意されているようです。
vueでいうところの、v-htmlと同じ様な感じですね。
<p class="app-card__text" set:html={text}></p>
この様な形にすると、改行タグが反映されます。
(おまけ)パス変更
相対パスではなく、@/形式で指定する方法は以下の通りです。
import { defineConfig } from "astro/config";
import { fileURLToPath } from "url";
import path, { dirname } from "path";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// https://astro.build/config
export default defineConfig({
vite: {
resolve: {
alias: {
"@/": `${path.resolve(__dirname, "src")}/`,
},
},
},
});