在这个实用的Astro指南中,我将指导你完成设置过程,并告诉你如何构造你的文件。你将学习如何添加页面、交互式组件,甚至是markdown文章。我还会告诉你如何从服务器上获取数据,创建布局,并使用vanilla JavaScript和其他框架添加互动性。准备好享受一些动手的乐趣,因为我们将一起创建一个小型的网站实例。我们将构建一个多页面的网站,包括一个博客。

在这篇文章末尾,你会很好地理解Astro是如何工作的,以及你如何使用它来更快地创建高效的网站。开始吧!

  • 什么是Astro框架?
  • Astro入门
  • Astro项目结构
  • Astro页面
  • Astro组件
  • 添加脚本
  • Astro布局
  • 元素
  • Astro组件props
  • Astro中的样式
  • 获取数据
  • 管理内容
  • 嵌套布局
  • 加载本地文件
  • 添加脚本
  • 使用UI框架
  • 指令
  • 构建和发布
  • 总结

什么是Astro框架?

作为开发人员,我们知道,在建设网站时,创造一个良好的用户体验是关键。而用户最喜欢的是什么?快速的网站,不浪费他们的时间。有了Astro,我们可以通过向浏览器发送更少的代码来实现这一目标。

我们都有自己喜欢的UI框架,使我们的生活更轻松,但它们可能会以沉重的网站为代价。但是有了Astro,我们就可以拥有两个世界中最好的东西。它允许我们用我们最喜欢的框架甚至多个框架同时构建我们的网站,但它在构建时将它们渲染成静态HTML。因此,我们可以为我们的用户创建一个快速的网站,而不牺牲现代开发者的体验。

但Astro并没有止步不前。它还允许我们在需要时加入动态的客户端JavaScript,这意味着我们可以在网站上拥有可交互的组件,但只在必要时进行。换句话说,Astro允许你从简单的开始,在需要时增加复杂性。

简而言之,Astro是一个强大的框架,它同时支持静态网站生成(SSG)和服务端渲染(SSR),帮助我们建立快速的、基于内容的网站,同时考虑到开发人员的体验。它轻量、高效、灵活,使它成为创建内容丰富的网站的合适选择,如博客、投资组合、文档和一些电子商务网站。如果你想创建一个具有大量交互的复杂应用程序,Astro可能不是你的正确选择。相反,你可以考虑其他工具比如Next.js。

很好,现在我们对Astro是什么以及它能做什么有了很好的了解。接下来,让我们继续研究,看看我们能一起构造些什么。

Astro入门

首先,让我们安装Astro并创建项目的模板。确保你的电脑上安装了Node.js v16.12.0或者更高版本。

npm create astro@latest

或者:

yarn create astro@latest

CLI会询问你的项目名称和你是否要使用Typescript。此外,它还会给你几个选项,告诉你如何设置你的项目。在本教程中,我选择了"一个空项目 "选项。

以下是我与Astro CLI的小型对话:

一旦你在编辑器中打开你的项目,你可以安装Astro的扩展。由于Astro有自己的文件扩展和语法,你可能想为你的编辑器安装其扩展。这里是VSCode的Astro扩展的链接,它不仅仅为你高亮语法,还能做得更多。

现在你可以用以下命令来运行你的项目。不需要安装任何依赖。

npm run dev

打开浏览器,访问http://localhost:3000/ ,一切就绪。

Astro项目结构

Astro的文件结构相当直截了当。

  • src:你的源码(组件、页面、样式等等)
  • public:你的静态资源(字体、图标等等)

src/pages目录下,Astro创建了一个index.astro,你可以认为这是index.html

值得注意的是,src/content/是Astro的一个保留目录。Astro v2.0引入了Collections API,用于将你的Markdown和MDX文件组织成内容集合。这个API保留了src/content/作为一个特殊的文件夹。

Astro页面

好了,让我们来谈谈Astro的页面。Astro页面处理路由、数据加载以及网站上每个页面的整体布局。它们是具有不同扩展名的文件,存在于src/pages/子目录中。

在Astro中,我们有不同类型的页面,包括.astro.md.mdx.html甚至是.js/.ts。每种文件类型都有不同的用途,可以用不同的方式来创建你的页面。

Astro使用一种称为基于文件路由的路由策略,这意味着你的src/pages/目录中的每个文件都会根据其文件路径成为你网站上的一个端点。这使得你的页面具有灵活性,并易于组织。

在本教程中,我们主要使用.astro.md文件来创建页面。注意,如果你使用.html页面,一些关键的Astro特性在HTML组件中不被支持。

现在让我们来创建第二个页面,看看它是如何工作的。你所需要做的就是在src/pages目录下创建一个紧挨着index.astro的文件。

我打算把它命名为about.astro,并在里面写上非常简单的标记语言:

<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<title>About</title>
</head>
<body>
<h1>About</h1>
<p>Jamstack development agency.</p>
</body>
</html>

现在你可以访问localhost:3000/about,在你的浏览器中看到这个页面。正如你所看到的,只要你把文件添加到pages文件夹中,/about路由就能立即发挥作用。

你可以更新内容,甚至添加你自己的内部样式,Astro将为你实时预览。所以不需要安装任何实时重载的NPM包或此类东西。

为了能够在页面之间轻松导航,我打算在我的index.astroabout.astro文件中添加导航:

<body>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
<h1>About</h1>
<p>Jamstack development agency.</p>
</body>

但你不希望每次在导航中增加一个链接时都要更新所有的页面,对吗?

这就是组件发挥作用的地方,让你不要重复你自己(DRY)。

Astro组件

Astro组件是任何Astro项目的基本构成模块。它们有两个主要部分:

  • 组件脚本
  • 组件模板

Astro组件长这样:

---
// Component Script (JavaScript)
---
<!-- Component Template (HTML + JS Expressions) -->

让我们为项目添加第一个组件。

我打算创建一个src/components目录,并在里面添加一个header.astro文件。接着,我会移动导航标记到Header组件中。目前为止,我们的组件的脚本部分是空白的。

---

---
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>

下一步是将该组件添加到我们的页面中。为了做到这一点,我们需要导入该组件。因此,打开你的about.astro文件,在文件的顶部添加以下导入内容:

---
import Header from '../components/Header.astro';
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<title>About</title>
</head>
<body>
<h1>About</h1>
<p>Jamstack development agency.</p>
</body>
</html>

现在,header组件已经导入了,可以这么使用:

<body>
<Header />
<h1>About</h1>
</body>

对主页做同样的事情,也就是pages目录中的index.astro文件。

现在,如果你在浏览器中查看这些页面,你应该看到header展现良好。

最后,我将把我们的logo和一些语义标记,与一个容器一起添加到我们的header中,这样我稍后可以添加一些样式:

<header>
<div class="container">
<a class="logo" href="/">
<svg><!-- SVG Logo goes here --></svg>
</a>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
</div>
</header>

这就是Astro的厉害之处。到目前为止,我们已经制作了页面,并向其添加了组件,而几乎不需要写任何HTML以外的东西。

添加脚本

代码栅栏是你的Astro组件的脚本部分。你可以用栅栏来写任何你需要的JavaScript来渲染你的模板。你甚至可以写TypeScript!

---
// The code fence area
---

例如,在上一节中,我在我的代码栅栏中添加了一个导入行,将Header组件添加到我的页面。我们将继续讨论我们在代码栅栏中还能做什么。

它被称为代码栅栏的原因是,无论你在其中写了什么JavaScript代码,都会被"围起来",不能逃到浏览器中去,也不能到你的用户手中。你在这里写的一切只是为了帮助你的组件模板。

让我们回到我们的页面,在页面的代码栅栏中添加一个变量,用于存储页面标题:

---
import Header from '../components/Header.astro';
const pageTitle = 'Bejamas';
---
<html lang="en">
<head>
<title>{pageTitle}</title>
</head>
<body>
<Header />
<h1>{pageTitle}</h1>
</body>
</html>

正如你在上面的片段中所看到的,你可以在代码栅栏内定义本地JavaScript变量,然后使用类似JSX的表达式将变量注入HTML模板中。

现在在你的其他页面比如about.astro等,可以做同样的事情。

当你查看不同页面时,你可能又开始注意到一些恼人的东西。是的,当你在不同的页面中写同样的东西时,你会重复自己。除了标题之外,你的页面中所有的代码都是完全一样的。

我想这是谈论Astro布局的一个好时机。

Astro布局

Astro布局只是具有不同名称的Astro组件,用于创建一个UI结构或布局,比如一个页面模板。因此,任何你能在组件中做到的事情,都有可能在布局中实现。

你可以把你的布局文件放在你项目的任何地方,但把它们添加到src/layouts目录中是很好的做法。

在我们的项目中,有一些跨页面的共享标记可以作为模板使用,以避免在不同的文件中重复它们。为了做到这一点,让我们在 src/layouts目录中创建一个 BaseLayout.astro 文件。

我们把index.astro的内容复制粘贴到该文件中:

你刚刚完成了你的第一个Astro布局,现在你需要在你的Astro页面中使用它。让我们看看你如何能做到这一点。

像组件一样,第一步是将布局导入到代码栅栏,然后通过在模板部分放置其标签来使用它。下面就是index.astro的样子:

---
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout></BaseLayout>

如果你试图为你的About页面做同样的事情,你会注意到about.astro里面有不同的内容。你需要保留它,或者以某种方式将它传递给你的BaseLayout文件。这就是<slot />的用武之地。

元素

<slot />元素是一个外部HTML内容的占位符。它指定了其他文件中的子元素应该被注入你的组件模板的位置。

你可以把这个元素添加到你的BaseLayout.astro文件中,就像下面的代码:

---
import Header from '../components/Header.astro';
const pageTitle = 'Bejamas';
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<title>{pageTitle}</title>
</head>
<body>
<Header />
<h1>{pageTitle}</h1>
<slot /> <!-- your content is injected here -->
</body>
</html>

现在,About页面的内容可以像这样放在BaseLayout标签之间:

---
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout>
<p>Jamstack development agency.</p>
</BaseLayout>

如果你查看你的浏览器,你会看到这两个页面是如何使用相同的模板但内容不同的。

只有一个部分被我们弄乱了,就是页面的标题。在我的例子中,两个标题都是 "Bejamas"。

这里就是组件props的用武之地!

Astro组件props

除了插槽,Astro组件的另一个特性是props,它在布局中可能非常有用。任何Astro组件都可以定义和接收props。要定义模板部分以外的props,你可以通过Astro.props全局设置。

在我们的例子中,我们可以定义一个pageTitle参数,并把它传递给我们的BaseLayout组件,以便能够在不同的页面上有不同的页面标题。

下面是你如何在BaseLayout组件中定义一个prop的例子:

---
import Header from '../components/Header.astro';
const { pageTitle } = Astro.props;
---
<html lang="en">
<head>
<title>{pageTitle}</title>
</head>
<body>
<Header />
<h1>{pageTitle}</h1>
<slot /> <!-- your content is injected here -->
</body>
</html>

注意我们是如何使用结构化语法从全局的Astro.props对象中取出props的。如果你有更多的props,你可以使用逗号分隔,就像下面这样:

const { pageTitle, pageDescription } = Astro.props;

现在,让我们看看你如何将一个prop传递到组件或者布局中。

index.astro页面可以将pageTitle作为属性进行传递:

---
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout pageTitle="Bejamas"></BaseLayout>

此外,你可以在脚本中定义变量更易于管理。在About页面中这样做:

---
import BaseLayout from '../layouts/BaseLayout.astro';
const pageTitle = 'About';
---
<BaseLayout pageTitle={pageTitle}>
<p>Jamstack development agency.</p>
</BaseLayout>

目前为止,我还没给你展示任何结果。原因是我们还缺少样式。那么我们就加一些CSS吧。

Astro中的样式

Astro项目可以用很多方法进行样式声明,我们在这里无法涵盖所有。然而你应该知道,Astro支持任何你能想到的方法。你可以编写纯CSS、Sass和CSS模块,甚至可以导入你喜欢的CSS库,比如Tailwind。

你可以直接在你的组件或页面模板上添加一个<style>标签。

---

---
<style>
.container { /* */ } nav {
display: flex;
gap: 1rem;
} nav a { /* */ }
</style>
<header>
<div class="container">
<a class="logo" href="/">
<svg><!-- SVG Logo goes here --></svg></a>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
</div>
</header>

Astro <style> CSS规则默认是在组件内起作用和封装的。这意味着写在这个组件中的样式不会泄漏,也不会影响你网站的其他部分。

除了Header组件外,我将把其余的样式添加到一个外部的CSS文件中,并在项目中作为全局样式导入。

下面是你如何将外部的CSS文件导入到BaseLayout.astro文件中的例子:

---
import Header from '../components/Header.astro';
import '../styles/global.css';
const { pageTitle } = Astro.props;
---
<html lang="en">
<head>
<title>{pageTitle}</title>
</head>
<body>
<Header />
<h1>{pageTitle}</h1>
<slot />
</body>
</html>

在我跳到下一节之前,我将在这里分享一个工作demo。我给我的HomeAbout页面添加了一些静态内容,并写了一些样式。

下面是我添加到我的主页的内容:

---
import BaseLayout from '../layouts/BaseLayout.astro';
const pageTitle = 'Bejamas';
---
<BaseLayout pageTitle={pageTitle}> <section class="section">
<div class="container">
<div class="banner">
<div class="">
<h3 class="pretitle">Jamstack Developers for hire</h3>
<h1 class="title">We build<br><mark>fast sites &amp; apps.</mark></h1>
<p class="text">Maximize your business potential...</p>
<a class="button" href="">Start project</a>
</div>
<img src="jam.svg" alt="" />
</div>
</div>
</section> </BaseLayout>

主页看起来长这样:

点击这里查看demo。

获取数据

我们教程的这一部分,我们将使用Bejamas API从服务器获取一些数据,并在我们的主页上创建这些案例研究卡。

在Astro中获取数据是非常容易的。你可以在你的代码栅栏中使用全局fetch()函数,在你的所有组件中向API发出HTTP请求。

index.astro中,我将添加这段代码,使用fetch()函数从服务器上获取案例研究的数据:

---
import BaseLayout from '../layouts/BaseLayout.astro';
const pageTitle = 'Bejamas';
const response = await fetch('bejamas.io/api/blog?category=case-studies');
const data = await response.json();
const posts = data.posts;
---

现在我有了posts变量中的数据,我可以用它来生成动态HTML,在我的主页上显示案例研究卡片。

下面是posts数组的样子:

"posts": [
{
"excerpt": "",
"mainImage": {
"asset": {
"url": ""
}
},
"slug": "",
"title": ""
}
]

我会使用map函数遍历posts,然后动态创建每张卡片:

<section class="section" id="casestudies-section">
<div class="container">
<h2 class="section-title">Case studies</h2>
<ul class="case-studies">
{posts.map((post) => (
<li>
<article class="casestudy">
<img src={post.mainImage.asset.url} alt="" />
<div>
<h3>{post.title}</h3>
<p>{post.excerpt}</p>
<a href={`https://bejamas.io/blog/${post.slug}`} class="">Read more</a>
</div>
</article>
</li>
))}
</ul>
</div>
</section>

最酷的是,所有这些都是在构建时发生的,我们将只向浏览器发送静态HTML。

这是向全局CSS添加样式后的结果:

点击这里查看demo。

管理内容

当涉及到创建和管理你的内容时,Astro给你两个选择:

  • Markdown
  • MDX

MDX类似于标准的Markdown,但有额外的功能。它允许你在你的Markdown内容中使用变量、JSX表达式和组件。

Astro内置了对Markdown的支持,但为了处理.mdx文件,你需要安装@astrojs/mdx进行集成。在本教程中,我们坚持使用标准的Markdown内容。

在我们进一步讨论之前,有必要提到Astro v2引入了内容集合,这是一种在Astro项目中组织内容的绝佳方式。我们将在未来的教程中写更多关于这个主题的内容。

正如我们前面所说的,由于静态路由在Astro中的工作方式,src/pages/目录中的任何页面都会得到一个路由。这意味着你可以在你的浏览器中打开它,或者在你的项目中的任何地方链接到它。另外,我们知道Markdown文件是Astro的一种页面类型,我们可以把它放在这个目录里面。牢记这些信息,让我们在 src/pages 目录中创建我们的第一个内容。

为了更有条理,我创建了一个blog文件夹,把我的.md文件放在那里,并把我的第一个Markdown内容添加到其中:

由于src/pages目录下的Astro组件(.astro)和Markdown文件(.md)会自动成为你网站上的页面,你可以简单地导航到以下URL,访问你的第一篇博文:

localhost:3000/blog/jamstack

你可以在你的Markdown的前言中添加更多关于你内容的信息,比如它的标题,发布日期,主要图片等等,就像下面这样:

---
title: 'Jamstack Explained'
pubDate: 2020-12-14
description: 'Jamstack is not about a specific technology…'
author: 'Denis Kostrzewa'
image:
url: '<https://bejamas.io/_next/image/?.>..'
alt: 'Jamstack Explained Photo'
--- # Jamstack Explained
Jamstack is no longer a buzzword over which dev keyword warriors brawl. It has grown to become a booming ecosystem of tools helping developers ship performant websites, progressive web apps, and other projects with benefits too good to ignore.

你当然不希望你的文章看起来像这样,肯定希望把你的网站设计融入其中,对吗?让我们为我们的博客内容创建一个布局。

src/layouts目录下添加一个名为BlogLayout.astro的文件,并将以下代码复制并粘贴到其中:

---
import Header from '../components/Header.astro';
import '../styles/global.css';
const { frontmatter } = Astro.props;
---
<html lang="en">
<head>
</head>
<body>
<Header />
<div class="container">
<div class="meta">
<div>
<time class="date">{frontmatter.pubDate.slice(0, 10)}</time>
<h1 class="title">{frontmatter.title}</h1>
<p class="description">{frontmatter.description}</p>
<span class="author">Author: <span class="author-name">{frontmatter.author}</span></span>
</div>
<img class="poster" src={frontmatter.image.url} alt={frontmatter.image.alt} />
</div>
<div class="body">
<slot />
</div>
</div>
</body>
</html>

请注意我们是如何使用Astro.props将frontmatter属性传递给这个布局的。现在你可以以任何方式将这些属性添加到你的模板中。

另外,注意插槽元素。这是内容出现在最终HTML页面上的地方。

还有一步。我们需要把这个布局添加到我们的内容中,所以我们回到我们的第一个Markdown文件,像以下代码那样做:

---
layout: ../../layouts/BlogLayout.astro
title: 'Jamstack Explained'
pubDate: 2020-12-14
description: 'Jamstack is not about a specific technology…'
author: 'Denis Kostrzewa'
image:
url: '<https://bejamas.io/_next/image/?.>..'
alt: 'Jamstack Explained Photo'
--- # Jamstack Explained
Jamstack is no longer a buzzword over which dev keyword warriors brawl. It has grown to become a booming ecosystem of tools helping developers ship performant websites, progressive web apps, and other projects with benefits too good to ignore.

正如你在第一行代码中所看到的,Astro有一个特殊的layout属性用于Markdown页面。这个属性定义了一个Astro布局组件的相对路径。

localhost:3000/blog/jamstack再次预览,看看布局给你的页面添加了什么。

嵌套布局

你是否注意到,我们不得不在我们的BlogLayout.astro布局中添加<head><body>标签?难道我们不能直接使用我们的BaseLayout来做这个吗?

因为Astor布局基本上是组件,那么我们可以嵌套它们。所以我们需要做的就是把我们的BaseLayout添加到新的BlogLayout.astro文件中:

---
import BaseLayout from "./BaseLayout.astro";
const { frontmatter } = Astro.props;
--- <BaseLayout pageTitle={frontmatter.title}>
<div class="container">
<div class="meta">
<div>
<time class="date">{frontmatter.pubDate.slice(0, 10)}</time>
<h1 class="title">{frontmatter.title}</h1>
<p class="description">{frontmatter.description}</p>
<span class="author">Author: <span class="author-name">{frontmatter.author}</span></span>
</div>
<img class="poster" src={frontmatter.image.url} alt={frontmatter.image.alt} />
</div>
<div class="body">
<slot />
</div>
</div>
</BaseLayout>

多么整洁,不是吗?

另外,注意到我们是如何将我们页面的标题传递给BaseLayout中的页面标题的:

<BaseLayout pageTitle={frontmatter.title}>

让我们给BlogLayout添加一些样式,我将在BlogLayout.astro文件中添加作用域内的样式:

---
import BaseLayout from "./BaseLayout.astro";
const { frontmatter } = Astro.props;
--- <style>
.container {
padding: 3rem 0;
max-width: 1152px;
} .meta {
display: flex;
align-items: center;
justify-content: space-between;
gap: 2rem;
} /* And more... */
</style> <BaseLayout pageTitle={frontmatter.title}>
<!-- ... -->
</BaseLayout>

现在页面看起来长这样:

我们需要做的最后一件事是在我们的主页上显示这些文章。

加载本地文件

在你的blog目录中添加更多的博客文章,这样我们就可以在我们的主页上创建一个列表。

Astro.glob()允许你将本地文件加载到你的静态页面上。它将返回一个对象数组,每个博客文章都有一个,包含所有关于你的Markdown文件的信息。

下面是你如何在你的index.astro文件中使用它:

---
const blogs = await Astro.glob('../pages/blog/*.md');
---

为了动态地生成整个文章列表,我们对Astro.glob()返回的博客数组进行map遍历,如以下代码:

<section class="section blog-section" id="blog-section">
<div class="container">
<h2 class="section-title">Our Blog</h2>
<ul class="blogs">
{blogs.map((blog) =>
<li>
<article class="blog">
<img src={blog.frontmatter.image.url} alt="blog.frontmatter.image.alt" />
<h3>{blog.frontmatter.title}</h3>
<p>{blog.frontmatter.description}</p>
<a href={blog.url} class="">Read more</a>
</article>
</li>
)}
</ul>
</div>
</section>

我们在index.astro文件中的案例研究部分下面添加了这个文件。

在浏览器中重新审视你的主页,享受你在页面底部添加的博客文章列表。在向global.css添加一些样式后,页面看起来是这样的:

如果你点击”Read more”链接,你会看到每篇文章的内容。

这里是目前为止项目的demo。

添加脚本

你可以使用标准的HTML <script>标签向你的Astro组件添加交互。这允许你发送JavaScript到浏览器中运行,并为你的Astro组件添加功能。例如,对于切换明亮模式到暗黑模式,你不需要一个JavaScript框架,你可以用普通的JavaScript来处理它。

.astro文件中,你可以用与HTML文件相同的标准方式添加客户端JavaScript:

<script>
console.log('Print this to the browser console');
</script> <!-- relative path to script at `src/scripts/local.js` -->
<script src="../scripts/local.js"></script> <!-- also works for local TypeScript files -->
<script src="./script-with-types.ts"></script> <script is:inline src="<https://my-extenrnal-script.com/script.js>"></script>

你添加的所有脚本将被处理并捆绑在Astro中,然后用type="module"注入到页面的<head>中。

如果你想避免捆绑脚本,你可以使用is:inline指令导入一个外部文件,就像例子中最后一个那样。

使用UI框架

Astro最引人注目的特点之一是它可以灵活地与你喜欢的JS框架集成。而且你不必只使用一个框架,你可以使用多个。

在我们的项目中,我想在主页的底部添加一个FAQ部分。我没有太多的时间,只想使用别人的作品,以便能够尽快创建我的页面。我搜索了一下FAQ的React组件,出现了一些链接。

那么问题来了,如何将React组件添加到你的项目中。

首先,你需要将React添加到你的项目中。在你的终端运行以下命令:

npx astro add react

你可以简单地在你的项目中编写自己的React组件,在src/components目录下添加一个.jsx文件。

由于我想导入一个React组件而不是自己写,所以我需要先把它添加到我的项目中。

所以我将用我的终端来安装这个包:

npm install react-faq-component

我将把FAQ.jsxFAQ.css文件添加到components目录中,并对我所导入的组件进行自定义:

import React, { useEffect, useState } from 'react';
import Faq from 'react-faq-component';
import './FAQ.css'; const data = {
rows: [],
}; const styles = {}; const config = {}; export default function FAQ() {
return <div>
<Faq
data={data}
styles={styles}
config={config}
/>
</div>;
}

你的组件一旦准备就绪,你就需要将其导入到页面中:

---
import BaseLayout from '../layouts/BaseLayout.astro';
import Faq from '../components/FAQ.jsx';
const pageTitle = "Bejamas";
---

接着在模板中随心所欲地使用:

<section class="section" id="faq-section">
<h2 class="section-title">Questions you probably want to ask</h2>
<div class="container faq-container">
<Faq />
</div>
</section>

下面是最终效果:

如果你在浏览器中进行查看,你会注意到该组件已经在你的页面上呈现了。然而它没有任何可交互性。由于动作不生效,当你点击按钮时,你无法展开子项。

我将在下一节向你展示我们需要的东西。

指令

正如你在上一个例子中看到的,这个组件被添加到了页面上,但它没有生效。发生这种情况是因为,默认情况下,你的框架组件只会在服务端渲染为静态HTML,所以,你的点击处理器或状态钩子就不会生效。这对于添加非交互式的组件非常有用,可以避免向客户端发送任何不必要的JavaScript。

你可以通过添加Astro指令使一个框架组件具有交互性(hydrated)。这些组件属性指明组件的JavaScript何时应该被发送到浏览器。

我在这里罗列出一些Astro的指令:

  • <Faq client:load /> 在页面加载时渲染该组件。
  • <Faq client:idle /> 一旦浏览器有空闲时间,就会渲染该组件。
  • <Faq client:visible /> 只有当该组件被滚动到视口范围中时才会渲染。
  • <Faq client:media="{media query here}" />只有在媒体查询生效的情况下才会渲染该组件。
  • <Faq client:only="react" /> 只在客户端渲染该组件,而不会在服务端渲染成静态HTML。

如果你不像上一个例子那样给你的组件添加任何这些东西,该组件的纯HTML版本将在浏览器中渲染,所以任何点击处理器或状态都不会生效。

我想在页面加载时加载我的FAQ组件,所以这就是我需要的:

<Faq client:load />

请注意,所有这些都来自于Astro中的Island Architecture

最后,这是我们的最终效果

构建和发布

Astro网站是开箱即用型的静态网站。这意味着所有的页面在最后都是静态HTML。因此,如果你拥有一台服务器,你部署网站的第一个选择是仅将你的最终HTML文件上传到你的服务器。

在你部署你的网站之前,你需要构建它。要做到这一点,你需要从你的Astro项目的根目录中运行构建命令。你可以通过在你的终端运行以下命令来做到这一点:

npm run build

项目的最终构建将被默认存储在dist文件夹中。所以,你需要做的就是把你的dist目录上传到你的服务器。 手动部署你的网站不是现在的首选方法。有大量的工具和服务可以为你自动完成整个工作流程。你所需要做的就是推送你的变化,他们将为你构建和部署项目。

你可以按照Astro网站上的指南,看看你如何在不同的部署服务上部署你的项目,如Netlify、Vercel、Deno等。

总结

总之,作为网络开发者,JavaScript框架的兴起赋予了我们诸多力量和丰富的体验。我们喜欢使用这些框架,因为它们使创建组件、共享和重用它们变得很容易。围绕使用Vue、React和Svelte等框架进行构建的工具是一流的。然而,使用这些框架的代价往往是在我们的页面上发送大量的JavaScript,即使是简单的静态内容。

有了Astro,我们就能得到两者的好处。我们仍然可以使用JSX和JavaScript编写动态内容,但Astro将其全部渲染成静态HTML,所以我们只加载我们真正需要的JavaScript。这样一来,我们的用户就有了快速、无缝的体验,而我们仍然可以享受到使用动态框架工作的所有好处。这对用户和开发者来说是一个双赢的局面!

以上就是本文的全部内容,如果对你有所帮助,欢迎点赞、收藏、转发~

从零开始使用 Astro 的实用指南的更多相关文章

  1. Chrome 控制台实用指南【转】

    转自伯乐在线. Chrome 控制台实用指南 前言 Chrome浏览器我想是每一个前端er必用工具之一吧,一部分原因是它速度快,体积不大,支持的新特性也比其它浏览器多,还有一部分我想就是因为它的控制台 ...

  2. A Practical Guide to Distributed Scrum - 分布式Scrum的实用指南 - 读书笔记

    最近读了这本IBM出的<A Practical Guide to Distributed Scrum>(分布式Scrum的实用指南),书中的章节结构比较清楚,是针对Scrum项目进行,一个 ...

  3. MSIL实用指南-生成索引器

    MSIL实用指南-生成索引器 索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item" ...

  4. webdriver实用指南python版本(1)-安装开发环境

    webdriver实用指南是本人编写的系列丛书,包括ruby版.python版和java版.在线版是免费的,之前是放在我的github上,但是很多同学总不记得地址,现在转到我的博客上,方便大家阅读. ...

  5. 乙醇的webdriver实用指南ruby版本

    webdriver实用指南是乙醇2013年分享计划的一部分,作为对已逝去的selenium2时代的追忆. 目录如下 启动浏览器 关闭浏览器 浏览器最大化 设置浏览器大小 访问链接 打印当前页面的tit ...

  6. [转载]Firefox插件(plugins)开发实用指南

    转自: http://huandu.me/2010/02/11/595/ Firefox插件可实现强大功能,但其中麻烦事情不少.写这个实用指南首先是为了方便自己记忆,免得以后再次栽倒一些坑里面,如果能 ...

  7. 《Android Studio实用指南》7.1 AndroidStudio代码检查工具概述

    本文节选自<Android Studio实用指南> 作者: 毕小朋 目前本书已上传到百度阅读, 在百度中搜索[Anroid Studio实用指南]便可以找到本书. Android Stud ...

  8. 《Android Studio实用指南》4.27 使用演示模式

    本文节选自<Android Studio实用指南> 第4章第27节 作者: 毕小朋 目前本书已上传到百度阅读, 在百度中搜索[Anroid Studio实用指南]便可以找到本书. 什么是演 ...

  9. 家用wifi信号覆盖增强扩展实用指南

    家用wifi信号覆盖增强扩展实用指南 现在网上很多号称穿墙王的无线路由器,但是一般用起来效果都不理想,其实最主要的原因还是家里面一般每个房间不大,但是墙比较多.并且一般也没有一个所谓的中心点放置路由器 ...

  10. EasyHook实用指南

    所谓实用指南就是全是干货,没那么多虚头巴脑的东西,真正要用的人会发现对自己有用的东西,浅尝辄止的人看起来会不知所云. FileMon自己实做的过程中遇到的问题: 1. exe和dll文件必须强命名,对 ...

随机推荐

  1. 【故障公告】cc攻击又来了,雪上加霜的三月

    非常非常抱歉!今天 21:20-22:10 左右,肆无忌惮的 cc 攻击又来了,蓄意攻击者很厉害,躲过阿里云云盾的黑洞机制,轻松击垮园子的博客站点,又给大家带来了很大的麻烦,请大家谅解! 今年3月是园 ...

  2. Java 2023年接地气的中高级面试题一(附答案)

    直入主题: Q1:为什么要用分布式锁? 在分布式系统中,多个进程或线程可能会同时访问共享资源,这可能会导致数据不一致.并发性问题.性能下降等问题.为了解决这些问题,我们通常会使用分布式锁来协调多个进程 ...

  3. 最强分布式搜索引擎——ElasticSearch

    最强分布式搜索引擎--ElasticSearch 本篇我们将会介绍到一种特殊的类似数据库存储机制的搜索引擎工具--ES elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以 ...

  4. DevOps 在未来将如何演进?丨行业观察

    自2007年 DevOps 这一概念推出以来,越来越多企业开始将开发和运维团队结合在一起,以加快部署速度,提高软件开发生命周期的效率和协作.但是,诸多因素都会对 DevOps 是否成功产生影响,例如组 ...

  5. 记一次在forEach中使用aynac/await中的坑

    1.背景 在写一个对齐脚本时 发现下列问题 const timeList = await imageList.map( (item,index)=>{ return item.identify_ ...

  6. 每日复习关于static 饿汉式 懒汉式,单例设计模式

    1.1.static 的使用 当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上的对象,只有通过 new 关键字才会产生出对象,这时系统才会分配内存空间给对象,其方法才可以供外部 ...

  7. 自己动手从零写桌面操作系统GrapeOS系列教程——1.2 GrapeOS真机演示

    学习操作系统原理最好的方法是自己写一个简单的操作系统. GrapeOS操作系统之前一直运行在模拟器和虚拟机中,今天我们来演示一下GrapeOS在真机上运行的情况. 一.物理机真机 今天演示用的真机是一 ...

  8. day33:进程锁&事件&进程队列&进程间共享数据

    目录 1.锁:Lock 2.信号量:Semaphone 3.事件:Event 4.进程队列:Queue 5.生产者和消费者模型 6.JoinableQueue 7.Manager:进程之间共享数据 锁 ...

  9. mysql导出csv

    1.正常查询 SELECT a.emp_no '员工号',b.seq '文章序号' from vote_records a INNER JOIN vote_content b ON a.vote_co ...

  10. 最好用的.NET敏捷开发框架-RDIFramework.NET V3.6版全新发布 100%源码授权

    RDIFramework.NET,基于.NET的快速信息化系统敏捷开发框架.10年沉淀.历经上千项目检验,致力于企业智能化开发,帮助提升软件开发效率.最好用的.NET开发框架,100%源码授权. 1. ...