1 2 3 4
| --- // 组件脚本(JavaScript) --- <!-- 组件模板(HTML + JS 表达式)-->
|
「Astro 组件语法」采用类似jsx的写法,不过他们还是有一些区别
区别1:属性采用 html 语法
1 2
| - <div className="box" dataValue="3" /> + <div class="box" data-value="3" />
|
区别2:没有根元素限制
1 2 3 4 5
| --- // 包含多个元素的模板 --- <p>无需将元素包装在单个容器元素中。</p> <p>Astro 支持模板中的多个根元素。</p>
|
区别3:多种注释写法
1 2 3 4
| --- --- <!-- HTML 注释语法在.astro 文件中是有效的 --> {/* JS 注释语法也是有效的 */}
|
模板语法
定义变量
1 2 3 4 5 6
| --- const name = "Astro"; --- <div> <h1>你好 {name}!</h1> <!-- 输出 <h1>你好 Astro!</h1> --> </div>
|
动态属性
1 2 3 4 5
| --- const name = "Astro"; --- <h1 class={name}>支持属性表达式</h1> <MyComponent templateLiteralNameAttribute={`MyNameIs${name}`} />
|
Fragment 片段
1 2 3 4 5
| --- const htmlString = '<p>Raw HTML content</p>'; --- <Fragment set:html={htmlString} /> <>helloe!!!</>
|
动态标签
1 2 3 4 5 6 7
| --- import MyComponent from "./MyComponent.astro"; const Element = 'div' const Component = MyComponent; --- <Element>Hello!</Element> <!-- 渲染成 <div>Hello!</div> --> <Component /> <!-- 渲染成 <MyComponent /> -->
|
条件渲染
1 2 3 4 5 6 7 8 9
| --- const isVisible = true; --- {#if isVisible} <p>Hello!</p> <!-- 渲染成 <p>Hello!</p> -->
{#else} <p>Goodbye!</p> {/if}
|
CSS 全局样式
1 2 3 4 5 6 7 8 9
| <style is:global> h1 { color: red; }
.text { color: blue; } </style>
|
Script 标签
Astro 允许你不使用任何框架,那么将会严格按照 html 进行编译,此时,此时你可以使用 script 标签处理事件,包括点击事件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| // <button class="alert" onClick={onClick}>Click me!</button> // 上面的点击写法是无效的
<button class="alert">Click me!</button>
<script> // 在页面上找到所有带有 `alert` 类的按钮。 const buttons = document.querySelectorAll('button.alert');
// 处理每个按钮上的点击事件。 buttons.forEach((button) => { button.addEventListener('click', () => { alert('按钮被点击了!'); }); }); </script>
|
指令
class:list
接收数组,其中有几种不同的可能值:
- string:添加到 class 元素
- Object:添加到键值对到 class 元素
- Array:扁平化
- false, null, or undefined: skipped
1 2 3 4
| <!-- 原先 --> <span class:list={[ 'hello goodbye', { world: true }, [ 'friend' ] ]} /> <!-- 输出 --> <span class="hello goodbye world friend"></span>
|
set:html={string}
将 HTML 字符串注入元素中,类似于设置 el.innerHTML
1 2 3 4 5 6 7
| --- const rawHTMLString = "Hello <strong>World</strong>" --- <h1>{rawHTMLString}</h1> <!-- 输出:<h1>Hello <strong>World</strong></h1> --> <h1 set:html={rawHTMLString} /> <!-- 输出:<h1>Hello <strong>World</strong></h1> -->
|
set:text={string}
将文本字符串注入元素中,类似于设置 el.innerText
。
客户端指令
默认情况下,UI 框架组件不会在客户端激活。如果没有 client:* 指令,它的 HTML 将被渲染到页面上,而无需 JavaScript。
client:load
立即加载并激活组件的 JavaScript。
client:idle
一旦页面完成了初始加载,并触发 requestIdleCallback 事件,就会加载并激活组件中的 JavaScript
client:visible
一旦组件进入用户的视口,就加载组件的 JavaScript 并使其激活
client:media
一旦满足一定的 CSS 媒体查询条件,就会加载并激活组件的 JavaScript。
client:only
跳过 HTML 服务端渲染,只在客户端进行渲染
1 2 3 4 5 6 7 8 9
| <BuyButton client:load /> <ShowHideButton client:idle /> <HeavyImageCarousel client:visible /> <SidebarToggle client:media="(max-width: 50em)" /> <SomeReactComponent client:only="react" /> <SomePreactComponent client:only="preact" /> <SomeSvelteComponent client:only="svelte" /> <SomeVueComponent client:only="vue" /> <SomeSolidComponent client:only="solid-js" />
|
组件
安装组件
在 astro.config.mjs 配置文件中添加如下
1 2 3 4 5 6 7 8
| import { defineConfig } from 'astro/config';
import react from "@astrojs/react";
// https://astro.build/config export default defineConfig({ integrations: [react()] });
|
添加组件
定义 React 组件
1 2 3 4 5 6 7
| import React from "react" import { useState } from "react" const ReactComponent = () => { const [count, setCount] = useState(0) return <div onClick={() => setCount(count + 1)}>React:{count}</div> } export default ReactComponent
|
引入组件
```astro
import Layout from ‘../layouts/Layout.astro’;
import ReactComponent from “../components/ReactComponent”;
``
他框架的流程类似
>> 只有在 .astro 文件中才可以使用多种框架的语言