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

Astro 组件的基本结构是什么?如何定义和使用 Props、插槽?

2月21日 16:14

Astro 组件使用 .astro 文件扩展名,具有独特的语法结构,结合了服务端代码和客户端模板。

组件结构:

astro
--- // 1. 前置脚本(Frontmatter) // 在这里编写服务端代码 const title = "我的博客文章"; const date = new Date().toLocaleDateString(); // 可以导入其他组件 import Card from './Card.astro'; // 可以执行异步操作 const posts = await fetch('/api/posts').then(r => r.json()); --- <!-- 2. 模板区域 --> <!-- 在这里编写 HTML/JSX --> <h1>{title}</h1> <p>发布于 {date}</p> <div class="posts"> {posts.map(post => ( <Card title={post.title} /> ))} </div> <style> /* 3. 样式作用域 */ h1 { color: #333; } </style>

三个主要部分:

  1. 前置脚本(Frontmatter)

    • 使用 --- 分隔符包裹
    • 在构建时执行,不会发送到浏览器
    • 可以使用 JavaScript/TypeScript
    • 支持导入、异步操作、数据处理
  2. 模板区域

    • 类似 HTML 的语法
    • 支持表达式插值 {variable}
    • 支持条件渲染 {condition && <Component />}
    • 支持列表渲染 {items.map(item => <Item />)}
  3. 样式作用域

    • 使用 <style> 标签
    • 默认是作用域样式(scoped)
    • 不会影响其他组件
    • 可以使用 :global() 选择器定义全局样式

Props 传递:

astro
--- // 子组件 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>

使用子组件:

astro
--- import Card from './Card.astro'; --- <Card title="文章标题" description="文章描述" />

插槽(Slots):

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

使用布局:

astro
--- import Layout from './Layout.astro'; --- <Layout title="我的页面"> <slot slot="header"> <h1>页面标题</h1> </slot> <p>主要内容</p> <slot slot="footer"> <p>页脚信息</p> </slot> </Layout>

TypeScript 支持:

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

注意事项:

  1. 前置脚本中的代码不会在浏览器中执行
  2. 模板中的表达式在构建时求值
  3. 样式默认是作用域的,不会泄漏
  4. 组件默认是静态的,需要交互时使用 client:* 指令
  5. 可以在组件中使用任何前端框架的组件

Astro 组件语法简洁而强大,提供了优秀的开发体验和性能表现。

标签:Astro