Skip to content

模板指令参考

模板指令是一种特殊的 HTML 属性,可在任何 Astro 组件模板(.astro 文件)中使用,有些也可以在 .mdx 文件中使用。

¥Template directives are a special kind of HTML attribute available inside of any Astro component template (.astro files), and some can also be used in .mdx files.

模板指令用于以某种方式控制元素或组件的行为。模板指令可以启用一些编译器功能,使你的生活更轻松(例如使用 class:list 而不是 class)。或者,指令可以告诉 Astro 编译器对该组件执行一些特殊操作(例如使用 client:load 进行水合)。

¥Template directives are used to control an element or component’s behavior in some way. A template directive could enable some compiler feature that makes your life easier (like using class:list instead of class). Or, a directive could tell the Astro compiler to do something special with that component (like hydrating with client:load).

本页描述了 Astro 中可用的所有模板指令以及它们的工作原理。

¥This page describes all of the template directives available to you in Astro, and how they work.

¥Rules

为了使模板指令有效,它必须:

¥For a template directive to be valid, it must:

  • 使用 X:Y 形式(例如:client:load)在其名称中包含冒号 :

  • 对编译器可见(例如:如果 attr 包含指令,<X {...attr}> 将不起作用)。

一些模板指令(但不是全部)可以采用自定义值:

¥Some template directives, but not all, can take a custom value:

  • <X client:load />(没有任何值)

  • <X class:list={['some-css-class']} />(采用一个数组)

模板指令永远不会直接包含在组件的最终 HTML 输出中。

¥A template directive is never included directly in the final HTML output of a component.

¥Common Directives

class:list={...} 获取类值数组并将它们转换为类字符串。这是由 @lukeed 流行的 clsx 辅助程序库提供支持的。

¥class:list={...} takes an array of class values and converts them into a class string. This is powered by @lukeed’s popular clsx helper library.

class:list 采用几个不同的可能值类型的数组:

¥class:list takes an array of several different possible value kinds:

  • string:添加到元素 class

  • Object:所有真实密钥都添加到元素 class

  • Array:flattened

  • falsenullundefined:skipped

<!-- This -->
<span class:list={[ 'hello goodbye', { world: true }, [ 'friend' ] ]} />
<!-- Becomes -->
<span class="hello goodbye world friend"></span>

set:html={string} 将 HTML 字符串注入到元素中,类似于设置 el.innerHTML

¥set:html={string} injects an HTML string into an element, similar to setting el.innerHTML.

Astro 不会自动转义该值!确保你信任该值,或者在将其传递给模板之前已手动对其进行转义。忘记这样做会让你面临 跨站脚本 (XSS) 攻击。

¥The value is not automatically escaped by Astro! Be sure that you trust the value, or that you have escaped it manually before passing it to the template. Forgetting to do this will open you up to Cross Site Scripting (XSS) attacks.

---
const rawHTMLString = "Hello <strong>World</strong>"
---
<h1>{rawHTMLString}</h1>
<!-- Output: <h1>Hello &lt;strong&gt;World&lt;/strong&gt;</h1> -->
<h1 set:html={rawHTMLString} />
<!-- Output: <h1>Hello <strong>World</strong></h1> -->

你还可以在 <Fragment> 上使用 set:html 以避免添加不必要的封装元素。从 CMS 获取 HTML 时,这尤其有用。

¥You can also use set:html on a <Fragment> to avoid adding an unnecessary wrapper element. This can be especially useful when fetching HTML from a CMS.

---
const cmsContent = await fetchHTMLFromMyCMS();
---
<Fragment set:html={cmsContent}>

set:html={Promise<string>} 将 HTML 字符串注入到封装在 Promise 中的元素中。

¥set:html={Promise<string>} injects an HTML string into an element that is wrapped in a Promise.

这可用于注入外部存储的 HTML,例如数据库中的 HTML。

¥This can be used to inject HTML stored externally, such as in a database.

---
import api from '../db/api.js';
---
<article set:html={api.getArticle(Astro.props.id)}></article>

set:html={Promise<Response>}响应 注入到元素中。

¥set:html={Promise<Response>} injects a Response into an element.

这在使用 fetch() 时最有帮助。例如,从以前的静态站点生成器中获取旧帖子。

¥This is most helpful when using fetch(). For example, fetching old posts from a previous static-site generator.

<article set:html={fetch('http://example/old-posts/making-soup.html')}></article>

set:html 可用于任何标记,并且不必包含 HTML。例如,在 <script> 标记上使用 JSON.stringify() 可将 JSON-LD 架构添加到页面。

¥set:html can be used on any tag and does not have to include HTML. For example, use with JSON.stringify() on a <script> tag to add a JSON-LD schema to your page.

<script type="application/ld+json" set:html={JSON.stringify({
"@context": "https://schema.org/",
"@type": "Person",
name: "Houston",
hasOccupation: {
"@type": "Occupation",
name: "Astronaut"
}
})}/>

set:text={string} 将文本字符串注入到元素中,类似于设置 el.innerText。与 set:html 不同,传递的 string 值会被 Astro 自动转义。

¥set:text={string} injects a text string into an element, similar to setting el.innerText. Unlike set:html, the string value that is passed is automatically escaped by Astro.

这相当于直接将变量传递到模板表达式中(例如:<div>{someText}</div>),因此该指令不常用。

¥This is equivalent to just passing a variable into a template expression directly (ex: <div>{someText}</div>) and therefore this directive is not commonly used.

¥Client Directives

这些指令控制 UI 框架组件 在页面上的水合方式。

¥These directives control how UI Framework components are hydrated on the page.

默认情况下,UI 框架组件不会在客户端中进行水合。如果未提供 client:* 指令,则其 HTML 将在没有 JavaScript 的情况下渲染到页面上。

¥By default, a UI Framework component is not hydrated in the client. If no client:* directive is provided, its HTML is rendered onto the page without JavaScript.

客户端指令只能用在直接导入到 .astro 组件中的 UI 框架组件上。使用 动态标签通过 components 属性传递的自定义组件 时不支持水合指令。

¥A client directive can only be used on a UI framework component that is directly imported into a .astro component. Hydration directives are not supported when using dynamic tags and custom components passed via the components prop.

  • 优先事项:高的

  • 对…有用:需要尽快进行交互的立即可见的 UI 元素。

在页面加载时立即加载并水合组件 JavaScript。

¥Load and hydrate the component JavaScript immediately on page load.

<BuyButton client:load />
  • 优先事项:中等的

  • 对…有用:不需要立即交互的优先级较低的 UI 元素。

页面完成初始加载并且 requestIdleCallback 事件触发后,加载并水合组件 JavaScript。如果你使用的浏览器不支持 requestIdleCallback,则使用文档 load 事件。

¥Load and hydrate the component JavaScript once the page is done with its initial load and the requestIdleCallback event has fired. If you are in a browser that doesn’t support requestIdleCallback, then the document load event is used.

<ShowHideButton client:idle />

Added in: astro@4.15.0

在补充组件之前等待的最长时间(以毫秒为单位),即使页面尚未完成初始加载。

¥The maximum time to wait, in milliseconds, before hydrating the component, even if the page is not yet done with its initial load.

这允许你传递 来自 requestIdleCallback() 规范的 timeout 选项 的值。这意味着你可以延迟对优先级较低的 UI 元素进行水化,并进行更多控制,以确保你的元素在指定的时间范围内具有交互性。

¥This allows you to pass a value for the timeout option from the requestIdleCallback() specification. This means you can delay hydration for lower-priority UI elements with more control to ensure your element is interactive within a specified time frame.

<ShowHideButton client:idle={{timeout: 500}} />
  • 优先事项:低的

  • 对…有用:低优先级 UI 元素要么位于页面下方 (“首屏以下”),要么加载时需要占用大量资源,如果用户从未见过该元素,你根本不希望加载它们。

一旦组件进入用户的视口,就加载并混合组件 JavaScript。这在内部使用 IntersectionObserver 来跟踪可见性。

¥Load and hydrate the component JavaScript once the component has entered the user’s viewport. This uses an IntersectionObserver internally to keep track of visibility.

<HeavyImageCarousel client:visible />

Added in: astro@4.1.0

或者,可以将 rootMargin 的值传递给底层 IntersectionObserver。指定 rootMargin 后,当组件周围指定的边距(以像素为单位)进入视口时,组件 JavaScript 将会水合,而不是组件本身。

¥Optionally, a value for rootMargin can be passed to the underlying IntersectionObserver. When rootMargin is specified, the component JavaScript will hydrate when a specified margin (in pixels) around the component enters the viewport, rather than the component itself.

<HeavyImageCarousel client:visible={{rootMargin: "200px"}} />

指定 rootMargin 值可以减少布局偏移(CLS),让组件在较慢的互联网连接上有更多的时间进行补充,并使组件更快地进行交互,从而增强页面的稳定性和响应能力。

¥Specifying a rootMargin value can reduce layout shifts (CLS), allow more time for a component to hydrate on slower internet connections, and make components interactive sooner, enhancing the stability and responsiveness of the page.

  • 优先事项:低的

  • 对…有用:侧边栏切换或其他可能仅在某些屏幕尺寸上可见的元素。

一旦满足特定的 CSS 媒体查询,client:media={string} 就会加载并水合组件 JavaScript。

¥client:media={string} loads and hydrates the component JavaScript once a certain CSS media query is met.

<SidebarToggle client:media="(max-width: 50em)" />

client:only={string} 跳过 HTML 服务器渲染,仅在客户端上渲染。它的行为类似于 client:load,因为它会在页面加载时立即加载、渲染和补充组件。

¥client:only={string} skips HTML server-rendering, and renders only on the client. It acts similarly to client:load in that it loads, renders, and hydrates the component immediately on page load.

你必须将组件的正确框架作为值传递!因为 Astro 不会在你构建期间/在服务器上运行该组件,所以 Astro 不知道你的组件使用什么框架,除非你明确告诉它。

¥You must pass the component’s correct framework as a value! Because Astro doesn’t run the component during your build / on the server, Astro doesn’t know what framework your component uses unless you tell it explicitly.

<SomeReactComponent client:only="react" />
<SomePreactComponent client:only="preact" />
<SomeSvelteComponent client:only="svelte" />
<SomeVueComponent client:only="vue" />
<SomeSolidComponent client:only="solid-js" />
<SomeLitComponent client:only="lit" />

¥Display loading content

对于仅在客户端上呈现的组件,也可以在加载时显示后备内容。在任何子元素上使用 slot="fallback" 来创建仅在客户端组件可用时才显示的内容:

¥For components that render only on the client, it is also possible to display fallback content while they are loading. Use slot="fallback" on any child element to create content that will be displayed only until your client component is available:

<ClientComponent client:only="vue">
<div slot="fallback">Loading</div>
</ClientComponent>

¥Custom Client Directives

从 Astro 2.6.0 开始,集成还可以添加自定义 client:* 指令来更改组件水合的方式和时间。

¥Since Astro 2.6.0, integrations can also add custom client:* directives to change how and when components should be hydrated.

访问 addClientDirective API 页面以了解有关创建自定义客户端指令的更多信息。

¥Visit the addClientDirective API page to learn more about creating a custom client directive.

¥Script & Style Directives

这些指令只能用在 HTML <script><style> 标记上,以控制客户端 JavaScript 和 CSS 在页面上的处理方式。

¥These directives can only be used on HTML <script> and <style> tags, to control how your client-side JavaScript and CSS are handled on the page.

默认情况下,Astro 自动将 <style> CSS 规则的范围限定到组件。你可以使用 is:global 指令选择退出此行为。

¥By default, Astro automatically scopes <style> CSS rules to the component. You can opt-out of this behavior with the is:global directive.

当包含该组件时,is:global 使 <style> 标记的内容在页面上全局应用。这会禁用 Astro 的 CSS 作用域系统。这相当于用 :global() 将所有选择器封装在 <style> 标记内。

¥is:global makes the contents of a <style> tag apply globally on the page when the component is included. This disables Astro’s CSS scoping system. This is equivalent to wrapping all of the selectors within a <style> tag with :global().

你可以将 <style><style is:global> 组合在同一个组件中,以创建一些全局样式规则,同时仍然限定大部分组件 CSS 的范围。

¥You can combine <style> and <style is:global> together in the same component, to create some global style rules while still scoping most of your component CSS.

See the Styling & CSS page for more details about how global styles work.
<style is:global>
body a { color: red; }
</style>

默认情况下,Astro 将处理、优化和打包在页面上看到的任何 <script><style> 标签。你可以使用 is:inline 指令选择退出此行为。

¥By default, Astro will process, optimize, and bundle any <script> and <style> tags that it sees on the page. You can opt-out of this behavior with the is:inline directive.

is:inline 告诉 Astro 在最终输出 HTML 中按原样保留 <script><style> 标记。内容不会被处理、优化或打包。这限制了一些 Astro 功能,例如导入 npm 包或使用 Sass 等编译为 CSS 的语言。

¥is:inline tells Astro to leave the <script> or <style> tag as-is in the final output HTML. The contents will not be processed, optimized, or bundled. This limits some Astro features, like importing an npm package or using a compile-to-CSS language like Sass.

is:inline 指令意味着 <style><script> 标签:

¥The is:inline directive means that <style> and <script> tags:

  • 不会被打包到外部文件中。这意味着控制外部文件加载的 诸如 defer 之类的属性 将不起作用。

  • 不会进行数据去重 — 元素出现的次数与渲染的次数一样多。

  • 不会相对于 .astro 文件解析其 import/@import/url() 引用。

  • 将在最终输出 HTML 中准确地渲染在其创作位置。

  • 样式将是全局的,并且不限于组件。

<style is:inline>
/* inline: relative & npm package imports are not supported. */
@import '/assets/some-public-styles.css';
span { color: green; }
</style>
<script is:inline>
/* inline: relative & npm package imports are not supported. */
console.log('I am inlined right here in the final output HTML.');
</script>
See how client-side scripts work in Astro components.

define:vars={...} 可以将服务器端变量从组件 frontmatter 传递到客户端 <script><style> 标记。支持任何 JSON 可序列化的 frontmatter 变量,包括通过 Astro.props 传递到组件的 props。值用 JSON.stringify() 序列化。

¥define:vars={...} can pass server-side variables from your component frontmatter into the client <script> or <style> tags. Any JSON-serializable frontmatter variable is supported, including props passed to your component through Astro.props. Values are serialized with JSON.stringify().

---
const foregroundColor = "rgb(221 243 228)";
const backgroundColor = "rgb(24 121 78)";
const message = "Astro is awesome!";
---
<style define:vars={{ textColor: foregroundColor, backgroundColor }}>
h1 {
background-color: var(--backgroundColor);
color: var(--textColor);
}
</style>
<script define:vars={{ message }}>
alert(message);
</script>

¥Advanced Directives

is:raw 指示 Astro 编译器将该元素的任何子元素视为文本。这意味着该组件内部所有特殊的 Astro 模板语法都将被忽略。

¥is:raw instructs the Astro compiler to treat any children of that element as text. This means that all special Astro templating syntax will be ignored inside of this component.

例如,如果你有一个将某些文本转换为 HTML 的自定义 Katex 组件,你可以让用户执行以下操作:

¥For example, if you had a custom Katex component that converted some text to HTML, you could have users do this:

---
import Katex from '../components/Katex.astro';
---
<Katex is:raw>Some conflicting {syntax} here</Katex>
Astro 中文网 - 粤ICP备13048890号