模板指令参考
模板指令是特殊的 HTML 属性,它可以在任一 Astro 组件模板(.astro
文件)中使用,也可以在 .mdx
文件中使用。
模板指令用某种方式控制元素或组件行为。模板指令可以启用一些编译器功能,使你的生活更轻松(比如使用 class:list
而不是 class
)。指令也可以让 Astro 编译器对该组件进行特殊处理(比如使用 client:load
激活组件)。
本页描述了 Astro 中所有可用的模板指令及其工作方式。
规则
段落标题 规则有效的模板指令需要:
- 在其名称中包括冒号
:
,使用X:Y
的形式(例如:client:load
)。 - 对编译器可见(例如:
<X {...attr}>
,如果attr
包含了指令,则不会工作)。
部分模板指令,可以传递自定义值:
<X client:load />
(无法传递值)<X class:list={['some-css-class']} />
(传递数组)
模板指令永远不会直接包含在组件的最终 HTML 输出中。
通用指令
段落标题 通用指令class:list
段落标题 class:listclass:list={...}
接收 class 数组,并将其转换为 class 字符串。这是受流行的 @lukeed clsx 辅助库的启发。
class:list
接收数组,其中有几种不同的可能值:
string
:添加到class
元素Object
:添加到键值对到class
元素Array
:扁平化false
,null
, orundefined
: 跳过
set:html
段落标题 set:htmlset:html={string}
将 HTML 字符串注入元素中,类似于设置 el.innerHTML
。
该值不会被 Astro 自动转义!请确保你信任该值,或者在传递给模板前对其进行手动转义。忘记这样做可能会使你受到跨网站脚本(XSS)攻击。
你也可以在 <Fragment>
上使用 set:html
来避免添加不必要的封装元素。这在从 CMS 获取 HTML 时特别有用。
set:html={Promise<string>}
将封装在 Promise 中的 HTML 字符串注入到元素中。
这可用于注入存储在外部的 HTML,例如在数据库中。
set:html={Promise<Response>}
将一个Response 响应注入到元素中。
这在使用 fetch()
时最有用。 例如,从以前的静态站点生成器中获取旧的文章。
set:html
可以用在任何标签上,不必包含 HTML。例如,在 <script>
标签上使用 JSON.stringify()
将 JSON-LD 模式添加到你的页面。
set:text
段落标题 set:textset:text={string}
将文本字符串注入元素中,类似于设置 el.innerText
。与 set:html
不同的是,传递的 string
值会被 Astro 自动转义。
这相当于直接将变量传入模板表达式(例如:<div>{someText}</div>
),因此这个指令并不常用。
客户端指令
段落标题 客户端指令这些指令描述了如何激活 UI 框架组件。
默认情况下,UI 框架组件不会在客户端激活。如果没有 client:*
指令,它的 HTML 将被渲染到页面上,而无需 JavaScript。
客户端指令只能用于直接引入到 .astro
组件中的 UI 框架组件。 使用 动态标签 和 通过 components
prop 传递的自定义组件 时,不支持 Hydration 指令。
client:load
段落标题 client:load- 优先级:高
- 适用于:立即可见的UI元素,需要尽快进行互动。
在页面加载时,立即加载并激活组件的 JavaScript。
client:idle
段落标题 client:idle- 优先级:中
- 适用于:优先级较低的 UI 元素,不需要立即进行互动。
一旦页面完成了初始加载,并触发 requestIdleCallback
事件,就会加载并激活组件中的 JavaScript。如果你所在的浏览器不支持 requestIdleCallback
,那么就会使用文档 load
事件。
timeout
段落标题 timeout
添加于:
astro@4.15.0
最大等待时间(以毫秒为单位),在此时间内即使页面尚未完成初始加载,也会对组件进行水合。
这允许你传递一个值给 requestIdleCallback()
规范中的 timeout
选项。这意味着你可以更灵活地延迟低优先级 UI 元素的水合,以确保你的元素在指定的时间范围内可交互。
client:visible
段落标题 client:visible- 优先级:低
- 适用于:低优先级 UI 元素,这些元素要么在页面的下方(折叠中),要么加载时非常耗费资源,如果用户没有看到这些元素,你宁愿不加载它们。
一旦组件进入用户的视口,就加载组件的 JavaScript 并使其激活。这在其内部使用 IntersectionObserver
来跟踪可见性。
client:visible={{rootMargin}}
段落标题 client:visible={{rootMargin}}
添加于:
astro@4.1.0
可选项,可以通过指定 rootMargin
,为底层的 IntersectionObserver
传递 rootMargin
值。当指定了 rootMargin
时,组件 JavaScript 将在组件周围指定的边距(以像素为单位)进入视口时进行水合,而不是组件本身。
指定 rootMargin
值可以减少布局移位(CLS),允许组件在较慢的互联网连接上进行更长时间的水合,并使组件更早地变得可交互,从而增强页面的稳定性和响应性。
client:media
段落标题 client:media- 优先级:低
- 适用于:侧边栏折叠或其他可能只在某些屏幕尺寸上可见的元素。
client:media={string}
一旦满足一定的 CSS 媒体查询条件,就会加载并激活组件的 JavaScript。
如果该组件在 CSS 中已隐藏,只在满足媒体查询条件时显示,那么只需使用 client:visible
就行,而不必传递相同的媒体查询给指令。
client:only
段落标题 client:onlyclient:only={string}
跳过 HTML 服务端渲染,只在客户端进行渲染。它的作用类似于 client:load
,它在页面加载时立即加载、渲染和润色组件。
你必须正确传递组件所用框架! 因为 Astro 不会在构建过程中/在服务器上运行该组件,Astro 不知道你的组件使用什么框架,除非你明确告诉它。
显示加载内容
段落标题 显示加载内容对于仅在客户端渲染的组件,还可以在加载时显示回退内容。在任何子元素上使用 slot="fallback"
来创建仅在客户端组件可用之前显示的内容:
自定义客户端指令
段落标题 自定义客户端指令自 Astro 2.6.0 版本开始,集成还可以添加自定义的 client:*
指令,以更改组件的注水方式和时机。
请访问 addClientDirective
API 页面,了解如何创建自定义的客户端指令。
脚本和样式指令
段落标题 脚本和样式指令这些指令只能用于 HTML 的 <script>
和 <style>
标签,以控制客户端 JavaScript 和 CSS 在页面上的处理方式。
is:global
段落标题 is:global默认情况下,Astro 会自动将 <style>
CSS 规则扩展到组件上。你可以用 is:global
指令禁用该行为。
is:global
使 <style>
标签的内容在包含该组件的页面上全面应用。这使得 Astro 的 CSS 作用域系统失效。这相当于用 :global()
来封装 <style>
标签内的所有选择器。
你可以在组件中同时使用 <style>
和 <style is:global>
,创建一些全局样式规则,同时仍对大部分组件 CSS 进行作用域控制。
is:inline
段落标题 is:inline默认情况下,Astro 会处理、压缩和打包它在页面上看到的任何 <script>
和 <style>
标签。你可以用 is:inline
指令禁用该行为。
is:inline
可以让 Astro 将 <script>
或 <style>
标签原封不动地留在最终输出的 HTML 中。这些内容将不会被处理、压缩或打包。它限制了 Astro 的一些功能,比如导入 npm 包或使用像 Sass 这样的 CSS 编译语言。
is:inline
指令意味着 <style>
和 <script>
标签:
- 不会被打包到外部文件中。这意味着控制外部文件加载的属性(如
defer
)将不起作用。 - 不会被重复使用——该元素会在渲染时出现多次。
- 它的
import
/@import
/url()
引用不基于.astro
文件地址进行解析。 - 将进行预处理,例如
<style lang="sass">
属性仍将生成纯 CSS。 - 将在最终输出的 HTML 中准确地呈现它所编写的位置。
- 样式将是全局性的,而不是对组件的范围。
只要在 <script>
或 <style>
标签上使用除 src
以外的任何属性,就相当于使用 is:inline
指令。
唯一例外的是在 <style>
标签上使用 define:vars
指令,它不会自动应用 is:inline
。
define:vars
段落标题 define:varsdefine:vars={...}
可以将服务器端的变量从组件 frontmatter 传递给客户端的 <script>
或 <style>
标签。支持任何 JSON 可序列化的 frontmatter 变量,包括通过 Astro.props
传递给组件的 props
。值可以使用 JSON.stringify()
进行序列化。
在 <script>
标签上使用 define:vars
相当于使用 is:inline
指令,这意味着脚本不会被打包,将直接内联到 HTML 中。
这是因为当 Astro 打包一个脚本时,即使你在一个页面上多次包含了包含脚本的组件,它也会包含并运行该脚本一次。define:vars
需要一个脚本来重新运行每组值,所以 Astro 创建了一个内联脚本来代替。
对于脚本,请尝试手动将变量传递给脚本。
高级指令
段落标题 高级指令is:raw
段落标题 is:rawis:raw
会让 Astro 编译器将该元素的任何子项都视为文本。这意味着该组件中所有特殊的 Astro 模板语法都不会生效。
例如,如果你有一个自定义的 Katex 组件,它将一些文本转换为 HTML,你可以这样做:
Reference