Astro Component:script 與 template 兩段結構
Astro 專案的基本組成單位。關鍵特性:HTML-only template,沒有 client-side runtime——預設不在瀏覽器渲染,HTML 在 build 時就產生好。
一個 component 分成兩段:上方 --- 圍起來的 script(在 build 時執行,可以直接 await fetch 私有 API 或資料庫),下方的 template。
---
import SomeAstroComponent from '../components/SomeAstroComponent.astro';
import SomeReactComponent from '../components/SomeReactComponent.jsx';
import someData from '../data/pokemon.json';
// Access passed-in component props, like `<X title="Hello, World" />`
const { title } = Astro.props;
// Fetch external data, even from a private API or database
const data = await fetch('SOME_SECRET_API_URL/users').then(r => r.json());
---
<!-- Your template here! -->Props
Define Props in component script block
---
interface Props {
title: string;
body: string;
href: string;
}
const { href, title, body } = Astro.props;
---Assign Default value to props
---
const { greeting = "Hello", name = "Astronaut" } = Astro.props;
---
<h2>{greeting}, {name}!</h2>Slot
use <slot/> to inject html to component
// children component
---
---
<h1>
<slot/>
</h1>
// parent component
---
---
<Children>
<span>test</span>
</Children>and we can pass name for different slot
// custome component
---
---
<div>
<slot/>
<slot name='second'/>
</div>---
import Custome from './custom.astro'
---
<Custom>
<span> one </span>
<span slot='second'> two </span>
<span> three </span>
</Custom>
you can setting default slot
---
---
<slot>
<p>This is my fallback content, if there is no child passed into slot</p>
</slot>by default slot will use HTML div to wrap, but we can use Fragment to cancel wrap
---
// Create a custom table with named slot placeholders for head and body content
---
<table class="bg-white">
<thead class="sticky top-0 bg-white"><slot name="header"/></thead>
<tbody class="[&_tr:nth-child(odd)]:bg-gray-100"><slot name="body"/></tbody>
</table>---
import CustomTable from './CustomTable.astro';
---
<CustomTable>
<Fragment slot="header"> <!-- pass table header -->
<tr><th>Product name</th><th>Stock units</th></tr>
</Fragment>
<Fragment slot="body"> <!-- pass table body -->
<tr><td>Flip-flops</td><td>64</td></tr>
<tr><td>Boots</td><td>32</td></tr>
<tr><td>Sneakers</td><td class="text-red-500">0</td></tr>
</Fragment>
</CustomTable>