框架组件

你可以在无需舍弃你所喜欢的组件框架的情况下使用 Astro 构建站点。

Astro 支持多个受欢迎的框架,包括 ReactPreactSvelteVueSolidJSAlpineJSLit

Astro 可供选择的有 React、Preact、Svelte、Vue、SolidJS、AlpineJS 和 Lit 集成。你可以在项目中选择安装和配置一个或多个 Astro 集成。

要在 Astro 中使用这些框架,首先要安装该集成以及任何相关的对等依赖。

npm install --save-dev @astrojs/react react react-dom

然后在 astro.config.mjs 中导入并添加函数到集成列表中:

astro.config.mjs
import { defineConfig } from 'astro/config';

import react from '@astrojs/react';
import preact from '@astrojs/preact';
import svelte from '@astrojs/svelte';
import vue from '@astrojs/vue';
import solid from '@astrojs/solid-js';
import lit from '@astrojs/lit';
import alpine from '@astrojs/alpinejs';

export default defineConfig({
  integrations: [react(), preact(), svelte(), vue(), solid(), lit(), alpine()],
});

⚙️ 阅读集成指引获取更多关于安装和配置 Astro 集成和信息。

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

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

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

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

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

框架组件可以使用 client:* 指令实现激活。它是个用来定义你的组件应该如何被渲染和激活的属性。

客户端指令描述了你的组件是否应该在构建时被渲染,以及你的组件的 JavaScript 何时应该被浏览器加载.

大多数指令会在构建时在服务器上渲染组件。组件 JS 将根据特定的指令被分发到客户端。当组件的 JS 导入完成后,组件将进行激活。

src/pages/interactive-components.astro
---
// 示例:浏览器中的激活框架组件。
import InteractiveButton from '../components/InteractiveButton.jsx';
import InteractiveCounter from '../components/InteractiveCounter.jsx';
---
<!-- 该组件 JS 将在页面加载开始时导入 -->
<InteractiveButton client:load />

<!-- 该组件 JS 将不会分发给客户端直到用户向下滚动,该组件在页面上是可见的 -->
<InteractiveCounter client:visible />

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

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

你可以在同一个 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>

向框架组件传递子组件

Section titled 向框架组件传递子组件

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

src/pages/component-children.astro
---
import MyReactSidebar from '../components/MyReactSidebar.jsx';
---
<MyReactSidebar>
  <p>Here is a sidebar with some text and a button.</p>
</MyReactSidebar>

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

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

src/pages/named-slots.astro
---
import MySidebar from '../components/MySidebar.jsx';
---
<MySidebar>
  <h2 slot="title">Menu</h2>
  <p>Here is a sidebar with some text and a button.</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>
src/components/MySidebar.jsx
export default function MySidebar(props) {
  return (
    <aside>
      <header>{props.title}</header>
      <main>{props.children}</main>
      <footer>{props.socialLinks}</footer>
    </aside>
  )
}

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

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

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

src/pages/nested-components.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>

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

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

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

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

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

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

我可以激活 Astro 组件吗?

Section titled 我可以激活 Astro 组件吗?

如果你试图使用 client: 修改器激活 Astro 组件,那是行不通的。。

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

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