Astro 组件是 Astro 项目的基础构建块。它们是纯 HTML、无需客户端运行时的模板组件。
如果懂 HTML,你就已经有足够的知识来编写你的第一个 Astro 组件了。
Astro 组件的语法是 HTML 的超集。该语法设计地让所有拥有编写 HTML 或 JSX 经验的人都感到熟悉,并增加包括对组件和 JavaScript 表达式的支持。你可以通过文件扩展名 .astro
来创建新的 Astro 组件。
Astro 组件非常灵活的。通常情况下,Astro 组件会包含一些可在页面中复用的 UI,如 header 或简介卡。在其他时候,Astro 组件可能包含一个较小的 HTML 片段,像是常见的使 SEO 更好的 <meta>
标签集合。Astro 组件甚至可以包含整个页面布局。
Astro 组件中最重要的一点是,它们在构建过程中会被渲染成 HTML。即使你在组件内运行 JavaScript 代码,它也会抢先一步运行从呈现给用户的最终页面中剥离出来。其最终使得网站变得更快,且默认不用任何 JavaScript。
Astro 组件是由两个主要部分所组成的——组件 script 和组件模板。每个部分分工处理最终呈现出一个既容易使用,又有足够的表现力来实现你的想象的框架。
你也可以在其他组件中使用组件以建立更多更先进的 UI。例如 Button
组件可以被用来创建 ButtonGroup
组件,像是这样。
Astro 使用代码栅栏(---
)来识别 Astro 组件中的组件脚本。如果你以前写过 Markdown,你可能已经熟悉了叫做 frontmatter 类似概念。Astro 的组件脚本的想法直接受到了这个概念的启发。
你可以使用组件脚本来编写渲染模板所需 JavaScript 代码。这可以包括:
- 导入其他 Astro 组件
- 导入其他框架组件,如 React
- 导入数据,如 JSON 文件
- 从 API 或数据库中获取内容
- 创建你要在模板中引用的变量
代码围栏的设计是为了保证你在其中编写的 JavaScript 被“围起来”。它不会逃到你的前端应用程序中,或落入你的用户手中。你可以安全地在这里写一些昂贵或敏感的代码(比如调用你的私人数据库),而不用担心它会出现在你的用户的浏览器中。
在组件脚本下面的是组件模板。组件模板决定了你的组件的 HTML 输出。
如果你在这里写普通的 HTML,你的组件将在任何 Astro 页面上呈现它被导入和使用的 HTML。
然而,Astro 的组件模板语法也支持 JavaScript 表达式、导入的组件和特殊的 Astro 指令。在组件脚本中定义的数据和值(在页面构建时)可以在组件模板中使用,以产生动态创建的 HTML。
你可以在 Astro 组件的 frontmatter 组件脚本内定义局部 JavaScript 变量。然后你就可以在组件的 HTML 模板中使用 JSX 表达式插入这些变量!
在 HTML 中可以通过大括号使用局部变量:
这些局部变量可以用大括号来传递属性值给 HTML 元素和组件。
局部变量可以在类似 JSX 的函数中使用,产生动态生成的 HTML 元素。
Astro 可以使用 JSX 逻辑运算符和三元表达式有条件地显示 HTML。
你也可以通过将一个变量设置为HTML标签名称或组件导入来使用动态标签。
Astro 组件模板可以渲染多个元素,而无需像 JavaScript 或 JSX 将所有内容包装在单个 <div>
或 <>
中。
但是,当使用类似表达式动态创建多元素时,你应该像在 JavaScript 或 JSX 中那样将这些多个元素包装在一个片段 中。Astro 支持使用 <Fragment> </Fragment>
或 <> </>
速记。
在使用 set:*
指令时,片段也用于避免使用包装元素,如下所示:
Astro 组件的语法是 HTML 的超集。它的设计使得任何有 HTML 或 JSX 经验的人都感到熟悉,但 .astro
文件和 JSX 之间有几个关键的区别。
在 Astro 中,所有 HTML 属性都使用标准的 kebab-case
格式,而不是 JSX 中使用的 camelCase
。这甚至适用于 class
,而 React 不支持。
在 Astro 中,你可以使用标准的 HTML 注释,而 JSX 会使用 JavaScript 风格的注释。
Astro 组件可以定义和接受参数。 然后,这些参数可用于组件模板以呈现 HTML。 可以在 frontmatter scsipt 中的 Astro.props
中使用。
这是一个接收 greeting
参数和 name
参数的组件示例。请注意,要接收的参数是从全局 Astro.props
对象中解构的。
你还可以使用 TypeScript 导出 Props
类型接口来定义参数。Astro 将自动选择任何导出的 props
接口,并为你的项目提供类型警告/错误提示。当从 Astro.props
解构时,这些参数也可以被赋予默认值。
你也可以通过导出 Props
类型接口,用 TypeScript 定义来参数。Astro 会自动接收任何导出的 Props
接口,并为你的项目提供类型警告/错误。这些道具也可以在从 Astro.props
解构时给出默认值。
当没有提供组件参数时,可以给它默认值来使用。
<slot />
元素是嵌入外部 HTML 内容的占位符,你可以将其他文件中的子元素注入(或“嵌入”)到组件模板中。
默认情况下,传递给组件的所有子元素都将呈现在 <slot />
中。
这种模式是 Astro 布局组件的基础:整个页面的 HTML 内容可以用 <Layout></Layout>
标签包裹并传递到 Layout 组件以在常见页面元素中呈现。
Astro 组件也可以有命名插槽。这允许你仅将具有相应插槽名称的 HTML 元素传递到插槽的位置。
在要传递给组件相应的 <slot name="my-slot"/>
占位符的子元素上使用 slot="my-slot"
属性。
插槽还可以渲染回退内容。当没有匹配的子元素传递给插槽时,<slot />
元素将呈现其自己的占位符子元素。
组件模板内部也支持 CSS <style>
标签。
它们可用于设置组件样式,并且所有样式规则都自动仅限用于组件范围内,以防止大型应用程序中的 CSS 冲突。
📚 有关应用样式的更多信息,请参阅我们的样式指南。
在不使用使用框架组件(React、Svelte、Vue、Preact、SolidJS、AlpineJS、Lit)或 Astro 集成(例如 astro-XElement)时,你可以在 Astro 组件模板中使用 <script>
标签使得该 JavaScript 可以在浏览器中使用。
默认情况下,<script>
标签由 Astro 处理:
- 任何导入都将被捆绑,允许你导入本地文件或 node 模块。
- 处理后的脚本将通过
type="module"
注入你页面的<head>
。
- 全面支持 TypeScript 包括导入 TypeScript 文件
- 如果你的组件在页面上多次使用,则脚本标签将只包含一次。
要避免捆绑脚本,你可以使用 is:inline
属性:
上述方法可以自由搭配组合,也可以在同一个 .astro
文件多次使用 <script>
标签。
📚 请参阅我们的指令参考页面以获取有关 <script>
标签上可用指令的更多信息。
什么时候用? 如果你的 JavaScript 文件处于 public/
中时。
请注意,当你使用下面提到的 import
方法时,该方法会跳过由 Astro 提供的 JavaScript 处理、捆绑和压缩。
什么时候用? 如果你的外部脚本位于 src/
中,并且它支持 ESM 模块类型时。
Astro 检测到这些 JavaScript 将在客户端导入,然后自动构建、压缩并将 JS 添加到页面中。
Astro 支持导入和使用 .html
文件作为组件,或者将这些文件放在 src/pages
子目录下作为页面。如果你正在复用一个没有使用框架的现有网站代码,或者你想确保你的组件没有动态功能,你可能会需要使用 HTML 组件。
HTML 组件必须只包含有效的 HTML,因此缺乏关键的 Astro 组件功能:
- 他们不支持 frontmatter、服务器端导入或动态表达。
- 无法捆绑任何
<script>
标签,就像他们有 is:inline
一样。
- 它们只能引用
public/
文件夹中的资产。
📚 阅读Astro 的内置组件。
📚 了解如何在你的 Astro 项目中使用 JavaScript 框架组件。