import IntegrationsNav from '/components/IntegrationsNav.astro' import ReadMore from '/components/ReadMore.astro'

你可以在无需舍弃你所喜欢的组件框架的情况下使用 Astro 构建站点。而是可以任意选择的 UI 框架来创建 Astro 群岛

官方的前端框架集成

Astro 支持多个流行的框架并提供了官方集成,包括 ReactPreactSvelteVueSolidJSAlpineJS

在我们的集成目录中找到更多 社区维护的框架集成(例如 Angular、Qwik、Elm 等)。

安装集成

你可以在你的项目中安装和配置一个或多个 Astro 集成。

查看集成指南以获取更多关于安装和配置 Astro 集成的信息。

:::tip 想要看看你选择的框架的示例?访问 astro.new 然后选择一个框架模板。 :::

使用框架组件

在 Astro 页面、布局和组件中就像 Astro 组件一样使用你的 JavaScript 框架组件。所有组件都可放在 /src/components 目录中,或者你也可以放在任何你喜欢的地方。

要使用框架组件,你需要在 Astro 组件脚本中使用相对路径导入它们。然后在其他组件、HTML 元素和类 JSX 表达式中使用它们。

astro
---import MyReactComponent from '../components/MyReactComponent.jsx';---<html>  <body>    <h1>Use React components directly in Astro!</h1>    <MyReactComponent />  </body></html>

默认情况下,你的框架组件将渲染为静态 HTML。这对于模板组件而言非常有用,它不需要交互和避免分发没用的 JavaScript 给用户。

激活组件

框架组件可以使用 client:* 指令来激活(hydrate)。这些是用于确定何时将组件的 JavaScript 发送到浏览器的组件属性。

使用除 client:only 以外的所有客户端指令,你的组件将首先在服务器上渲染以生成静态 HTML。根据你选择的指令,将向浏览器发送组件 JavaScript。然后组件将被激活并变成可交互式的。

astro
---// 示例:在浏览器中激活框架组件。import InteractiveButton from '../components/InteractiveButton.jsx';import InteractiveCounter from '../components/InteractiveCounter.jsx';import InteractiveModal from '../components/InteractiveModal.svelte';---<!-- 该组件的 JS 将在页面加载开始时导入 --><InteractiveButton client:load /><!-- 该组件的 JS 将不会发送给客户端,直到用户向下滚动到该组件在页面上可见时 --><InteractiveCounter client:visible /><!-- 这个组件不会在服务端渲染, 但是在页面加载时将渲染在客户端 --><InteractiveModal client:only="svelte" />

组件渲染所需的 JavaScript 框架(React、Svelte 等)将与组件自己的 JavaScript 一起发送到浏览器。如果页面上的两个或多个组件使用相同的框架,则该框架将只发送一次。

:::note[无障碍] 在 Astro 中使用这些组件时,大多数框架特定的无障碍模式应该是一样的。请确保选择一个客户端指令,以确保任何与可访问性相关的 JavaScript 在适当的时间被正确加载和执行! :::

可用激活指令

这里有几个适用于 UI 框架组件的激活指令:client:loadclient:idleclient:visibleclient:media={QUERY}client:only={FRAMEWORK}

查看指令参考页面获取这些激活指令的详细描述以及用法。

混合框架

你可以在同一个 Astro 组件中导入并渲染来自多个框架的组件。

astro
---// src/pages/mixing-frameworks.astro// 示例:在同一个页面混合多个框架的组件。import MyReactComponent from '../components/MyReactComponent.jsx';import MySvelteComponent from '../components/MySvelteComponent.svelte';import MyVueComponent from '../components/MyVueComponent.vue';---<div>  <MySvelteComponent />  <MyReactComponent />  <MyVueComponent /></div>

:::caution 只有 Astro 组件(.astro)可以包括多个框架的组件 :::

向框架组件传递 Props

你可以从 Astro 组件向框架组件传递 props:

astro
---import TodoList from '../components/TodoList.jsx';import Counter from '../components/Counter.svelte';---<div>  <TodoList initialTodos={["learn Astro", "review PRs"]} />  <Counter startingCount={1} /></div>

:::caution[向框架组件传递函数] 你可以向框架组件传递函数,但是只有在服务器渲染时才有效。如果你在激活的组件中尝试使用该函数(例如作为事件处理程序),则会发生错误。

这是因为函数无法被 Astro 序列化(从服务器传输到客户端)。 :::

向框架组件传递子组件

在 Astro 组件中,你可以向框架组件传递子组件。每个框架都有自己的模式来引用这些子组件:React、Preact 和 Solid 均使用一个特殊的属性名 children,而 Svelte 和 Vue 则使用 <slot /> 元素。

astro
---import MyReactSidebar from '../components/MyReactSidebar.jsx';---<MyReactSidebar>  <p>这里是一个带有一些文字和一个按钮的侧边栏。</p></MyReactSidebar>

另外你可以使用命名插槽来区分特定的子组件。

对于 React、Preact 和 Solid,这些插槽都会转换成顶级属性。使用 kebab-case 的插槽名会转换成 camelCase

astro
---import MySidebar from '../components/MySidebar.jsx';---<MySidebar>  <h2 slot="title">菜单</h2>  <p>这里是一个带有一些文字和一个按钮的侧边栏。</p>  <ul slot="social-links">    <li><a href="https://twitter.com/astrodotbuild">Twitter</a></li>    <li><a href="https://github.com/withastro">GitHub</a></li>  </ul></MySidebar>
jsx
// src/components/MySidebar.jsxexport default function MySidebar(props) {  return (    <aside>      <header>{props.title}</header>      <main>{props.children}</main>      <footer>{props.socialLinks}</footer>    </aside>  )}

针对 Svelte 和 Vue 的插槽会使用 <slot> 元素进行引用。而使用 kebab-case 的插槽名会保留。

jsx
// src/components/MySidebar.svelte<aside>  <header><slot name="title" /></header>  <main><slot /></main>  <footer><slot name="social-links" /></footer></aside>

嵌套框架组件

在 Astro 文件中,框架组件子项也是激活组件。这意味着你可以嵌套地使用这些框架组件。

astro
---import MyReactSidebar from '../components/MyReactSidebar.jsx';import MyReactButton from '../components/MyReactButton.jsx';import MySvelteButton from '../components/MySvelteButton.svelte';---<MyReactSidebar>  <p>这里是一个带有一些文字和一个按钮的侧边栏。</p>  <div slot="actions">    <MyReactButton client:idle />    <MySvelteButton client:idle />  </div></MyReactSidebar>

:::caution 记住:框架组件文件(例如 .jsx.svelte)不能混合多个框架。 :::

这使得你可以用喜欢的 JavaScript 框架中建立整个应用,并通过在 Astro 页面中使用父组件来渲染它们。

:::note 即使 Astro 组件包括激活框架组件,它也会被渲染成静态 HTML。这意味着,你只能传递不做任何 HTML 渲染的参数。在 Astro 组件中向框架组件传递 React 的“渲染参数”是行不通的,因为 Astro 组件无法提供该模式所需要的客户端运行时行为。所以请改用命名插槽。 :::

我可以在我的框架组件中使用 Astro 组件吗?

任何 UI 框架组件都会成为该框架的一个“孤岛”。这些组件必须完全作为该框架的有效代码来编写,只使用它自己的导入和包。你不能在一个 UI 框架组件(如 .jsx.svelte)中导入 .astro 组件。

不过你可以在.astro组件内使用 Astro <slot /> 模式将 Astro 组件生成的静态内容作为子项传递给框架组件。

astro
---import MyReactComponent from  '../components/MyReactComponent.jsx';import MyAstroComponent from '../components/MyAstroComponent.astro';---<MyReactComponent>  <MyAstroComponent slot="name" /></MyReactComponent>

我可以激活 Astro 组件吗?

如果你试图使用 client: 修饰符激活 Astro 组件,你将收到错误消息。

Astro 组件是纯 HTML 的模板组件,没有客户端运行时。但是,你可以在 Astro 组件模板中使用 <script> 标签,向浏览器发送在全局范围内执行的 JavaScript。

了解更多关于 Astro 组件中的客户端 <script> 的信息。