乐闻世界logo
搜索文章和话题

What is the basic structure of Astro components? How do you define and use Props and Slots?

2月21日 16:14

Astro components use the .astro file extension and have a unique syntax structure that combines server-side code and client-side templates.

Component Structure:

astro
--- // 1. Frontmatter // Write server-side code here const title = "My Blog Post"; const date = new Date().toLocaleDateString(); // Can import other components import Card from './Card.astro'; // Can perform async operations const posts = await fetch('/api/posts').then(r => r.json()); --- <!-- 2. Template Area --> <!-- Write HTML/JSX here --> <h1>{title}</h1> <p>Published on {date}</p> <div class="posts"> {posts.map(post => ( <Card title={post.title} /> ))} </div> <style> /* 3. Scoped Styles */ h1 { color: #333; } </style>

Three Main Parts:

  1. Frontmatter:

    • Wrapped with --- delimiters
    • Executes at build time, not sent to browser
    • Can use JavaScript/TypeScript
    • Supports imports, async operations, data processing
  2. Template Area:

    • HTML-like syntax
    • Supports expression interpolation {variable}
    • Supports conditional rendering {condition && <Component />}
    • Supports list rendering {items.map(item => <Item />)}
  3. Scoped Styles:

    • Uses <style> tag
    • Default is scoped styles
    • Won't affect other components
    • Can use :global() selector for global styles

Props Passing:

astro
--- // Child component Card.astro const { title, description } = Astro.props; --- <div class="card"> <h2>{title}</h2> <p>{description}</p> </div> <style> .card { border: 1px solid #ddd; padding: 1rem; } </style>

Using child component:

astro
--- import Card from './Card.astro'; --- <Card title="Article Title" description="Article Description" />

Slots:

astro
--- // Layout.astro const { title } = Astro.props; --- <html> <head> <title>{title}</title> </head> <body> <header> <slot name="header" /> </header> <main> <slot /> <!-- Default slot --> </main> <footer> <slot name="footer" /> </footer> </body> </html>

Using layout:

astro
--- import Layout from './Layout.astro'; --- <Layout title="My Page"> <slot slot="header"> <h1>Page Title</h1> </slot> <p>Main Content</p> <slot slot="footer"> <p>Footer Information</p> </slot> </Layout>

TypeScript Support:

astro
--- interface Props { title: string; count?: number; } const { title, count = 0 } = Astro.props satisfies Props; --- <h1>{title}</h1> <p>Count: {count}</p>

Important Notes:

  1. Code in frontmatter doesn't execute in the browser
  2. Expressions in templates are evaluated at build time
  3. Styles are scoped by default and won't leak
  4. Components are static by default, use client:* directives for interactivity
  5. Can use components from any frontend framework in Astro components

Astro component syntax is simple yet powerful, providing excellent developer experience and performance.

标签:Astro