Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >从零开始使用 Astro 的实用指南

从零开始使用 Astro 的实用指南

作者头像
chuckQu
发布于 2023-09-01 01:28:51
发布于 2023-09-01 01:28:51
1.3K00
代码可运行
举报
文章被收录于专栏:前端F2E前端F2E
运行总次数:0
代码可运行

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

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

什么是Astro框架?

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

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

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

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

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

Astro入门

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
npm create astro@latest

或者:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
yarn create astro@latest

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

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

image.png

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
npm run dev

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

Astro项目结构

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

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

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

image.png

值得注意的是,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,并在里面写上非常简单的标记语言:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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文件中添加导航:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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组件长这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
// Component Script (JavaScript)
---
<!-- Component Template (HTML + JS Expressions) -->

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
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组件已经导入了,可以这么使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<body>
  <Header />
  <h1>About</h1>
</body>

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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!

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
// The code fence area
---

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
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的内容复制粘贴到该文件中:

image.png

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout></BaseLayout>

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

元素

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
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标签之间:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
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的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
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,你可以使用逗号分隔,就像下面这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const { pageTitle, pageDescription } = Astro.props;

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout pageTitle="Bejamas"></BaseLayout>

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
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>标签。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---

---
<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文件中,并在项目中作为全局样式导入。

image.png

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
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页面添加了一些静态内容,并写了一些样式。

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
  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>

主页看起来长这样:

image.png

点击这里[3]查看demo。

获取数据

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
  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数组的样子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"posts": [
  {
    "excerpt": "",
    "mainImage": {
      "asset": {
        "url": ""
      }
    },
    "slug": "",
    "title": ""
  }
]

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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添加样式后的结果:

image.png

点击这里[4]查看demo。

管理内容

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

  • Markdown
  • MDX

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

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

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

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

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

image.png

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
localhost:3000/blog/jamstack

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
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的文件,并将以下代码复制并粘贴到其中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
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文件,像以下代码那样做:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
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文件中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
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中的页面标题的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<BaseLayout pageTitle={frontmatter.title}>

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
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>

现在页面看起来长这样:

image.png

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

加载本地文件

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
  const blogs = await Astro.glob('../pages/blog/*.md');
---

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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添加一些样式后,页面看起来是这样的:

image.png

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

这里[7]是目前为止项目的demo。

添加脚本

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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添加到你的项目中。在你的终端运行以下命令:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
npx astro add react

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
npm install react-faq-component

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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>;
}

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
  import BaseLayout from '../layouts/BaseLayout.astro';
  import Faq from '../components/FAQ.jsx';
  const pageTitle = "Bejamas";
---

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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>

下面是最终效果:

image.png

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

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

指令

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

你可以通过添加Astro指令[8]使一个框架组件具有交互性(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组件,所以这就是我需要的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<Faq client:load />

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

最后,这是我们的最终效果[10]。

构建和发布

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
npm run build

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

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

总结

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

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

  • 本文译自:https://bejamas.io/blog/practical-guide-to-astro-js-framework/[12]
  • 作者:Mojtaba Seyedi

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

参考资料

[1]

链接: https://marketplace.visualstudio.com/items?itemName=astro-build.astro-vscode

[2]

http://localhost:3000/: http://localhost:3000/

[3]

这里: https://stackblitz.com/edit/withastro-astro-nkdbmu?embed=1&file=src/layouts/BaseLayout.astro

[4]

这里: https://stackblitz.com/edit/withastro-astro-eyreix?embed=1&file=src/styles/global.css

[5]

@astrojs/mdx: https://docs.astro.build/en/guides/integrations-guide/mdx/

[6]

内容集合: https://docs.astro.build/en/guides/content-collections/

[7]

这里: https://stackblitz.com/edit/withastro-astro-zszfry?ctl=1&embed=1&view=preview

[8]

Astro指令: https://docs.astro.build/en/reference/directives-reference/#client-directives

[9]

Island Architecture: https://docs.astro.build/en/concepts/islands/

[10]

最终效果: https://stackblitz.com/edit/bejamas-astro-demo?embed=1&file=README.md&view=preview

[11]

指南: https://docs.astro.build/en/guides/deploy/

[12]

https://bejamas.io/blog/practical-guide-to-astro-js-framework/: https://bejamas.io/blog/practical-guide-to-astro-js-framework/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端F2E 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
新型web框架Astro快速构建内容网站
Astro 是集多功能于一体的 Web 框架,用于构建快速、以内容为中心的网站,可集成Vue、React、Tailwind、Svelte等多种前端框架,可快速构建个人博客、文档网站和公司官网等内容网站
Petrochor
2023/04/01
3.3K0
新型web框架Astro快速构建内容网站
🚀🚀🚀Astro:一个可以同时写React、Vue、Svelte、SolidJS等多种语言的框架
Astro 是「集多功能于一体的 Web 框架」,用于构建「快速、以内容为中心」的网站。
萌萌哒草头将军
2023/08/31
1.5K0
🚀🚀🚀Astro:一个可以同时写React、Vue、Svelte、SolidJS等多种语言的框架
astro
在前端框架百花齐放的今天,React、Vue、Svelte 等已经牢牢占据开发者的视野。而 Astro,则以一种“反潮流”的方式切入了战场——它不试图成为全能框架,而是专注于一个核心场景:内容驱动的静态网站。
阿超
2025/03/27
1000
使用Astro、Qwik 和 Fuse.js构建网站搜索
利用 Astro 的内容集合、静态端点和 Qwik 的 Astro 集成以及 Fuse.js,构建网站搜索功能的方法。
云云众生s
2024/03/28
1820
使用Astro、Qwik 和 Fuse.js构建网站搜索
Astro,你真的值得试试……
上周我写了一篇关于我对 Next.js 的失望的文章。不过我接下来希望写点正能量的内容,那必须是我最喜欢的 Astro 了。
ssh_晨曦时梦见兮
2023/10/14
5350
使用vue构建企业级应用步骤
在main.js中导入babel-polyfill 以便旧版浏览器中可以使用新的js特性
lilugirl
2019/12/16
7650
一个现代静态网站生成器Eleventy
我们展示了Eleventy如何提供一种流畅的Web开发过程,与现有技术协同工作,同时引导您采用良好的实践。
云云众生s
2024/03/28
1840
一个现代静态网站生成器Eleventy
06 . Vue路由简介,原理,实现及嵌套路由,动态路由,编程式导航
基于URL的hash实现(点击菜单的时候改变URL的hash,根据hash的变化控制组件的切换)
iginkgo18
2020/11/24
2K0
06 . Vue路由简介,原理,实现及嵌套路由,动态路由,编程式导航
Blazor学习之旅(7)布局
Blazor 中的布局可以让我们编写的页面具有相同的导航菜单和页头页脚部分,提高通用代码的复用性,通过一次性的编写通用代码从而减少重复劳动。
Edison Zhou
2023/07/31
4640
Blazor学习之旅(7)布局
Blade 模板引擎进阶篇
除了基本的数据渲染及控制结构指令之外,Blade 还提供了模板继承和组件引入功能,从而允许视图模板之间继承、覆盖及引入。
学院君
2020/10/30
3.9K0
Blade 模板引擎进阶篇
从零开始使用create-react-app + react + typescript 完成一个网站
也许有人咋一看,看到这个网站有些熟悉,没错,这个网站来源于jsisweird.com/。我花了三天时间,用 create-react-app + react + typescript 重构这个网站,与网站效果不同的是,我没有加入任何的动画,并且我添加了中英文切换以及回到顶部的效果。
陈大鱼头
2021/10/09
1.7K0
从零开始使用create-react-app + react + typescript 完成一个网站
Astro.js 中集成 Vue 框架教程
Astro的集成能力支持我们使用Vue3编写的组件,并且支持SSR(server-side rendering)和CSH(client-side hydration)
泯泷、
2024/03/17
4680
Astro.js 中集成 Vue 框架教程
HTML入门完全指南:从零开始构建你的第一个网页
每个网页都会有一个基本的结构标签(也称为骨架标签),页面内容也是在这些基本标签上写
IsLand1314
2025/03/08
6880
HTML入门完全指南:从零开始构建你的第一个网页
用 Gatsby 创建一个博客
Gatsby 是一个令人难以置信的静态站点生成器,它允许使用React作为渲染引擎引擎来搭建一个静态站点,它真正具有现代web应用程序所期望的所有优点。它通过在构建时通过服务器端渲染将动态的 react 组件呈现为静态 HTML 内容。这意味着您的用户可以获得静态站点的所有好处,比如不使用JavaScript、搜索引擎友好性、非常快的加载速度等等,也并没有失去现代web所期望的活力和交互性。一旦呈现为静态 HTML,客户端站点的React和JavaScript会接管它并添加动态的内容。 Gatsby 最近发布了v1.0.0,推出了很多新特性。包括(但不限于)使用GraphQL创建内容查询的能力,与各种cms集成——包括WordPress、Contentful、Drupal等等。还有基于路由的代码分布使得用户体验更佳。在这篇文章中,我们将深入探讨 Gatsby 和一些新特性,并创建一个静态博客。让我们开始吧!
疯狂的技术宅
2019/03/27
2.7K0
用 Gatsby 创建一个博客
前后端分离之vue2.0+webpack2 实战项目 -- html模板拼接
对于前后端分离,如何把一个页面的公共部分比如head, header, footer, content等组合成一个完整的html 是一个值得考虑的地方。 对于php,我们可以利用include加载其他页面,像yii框架,可以利用render将输出的内容嵌入到父模板,从而形成一个完整的页面。 那对于纯静态的html我们如何拼接呢? 可以想到市面上的多种模板引擎,比如artTemplate, doT, ejs等,他们可以使用require或include等特殊标记的语法来引入其他模块。但如果每个页面我们都去写若
smy
2018/04/03
1.6K0
前后端分离之vue2.0+webpack2 实战项目 -- html模板拼接
Astro 3.0 闪亮登场,让你轻松构建更快速、更流畅的前端应用
网站前端开发的领域不断演进,随着Astro 3.0的发布,它正在迈出巨大的一步。Astro 3.0引入了突破性的功能和增强功能,承诺改变我们构建和体验网络应用程序的方式。在本文中,我们将探讨Astro 3.0的主要亮点以及如何赋予开发人员创建更快、更引人入胜和视觉上令人惊叹的网络体验的能力。
前端达人
2023/09/11
4980
Astro 3.0 闪亮登场,让你轻松构建更快速、更流畅的前端应用
2018年laravel教程第1节搭建项目phpstorm添加laravel代码提示新建路由和控制器渲染页面定义公共模板文件公共头部和底部小结
PHP框架哪家强?这个问题估计得让PHPer撕起来,别的指标不说,仅从github的受欢迎程度来讲,laravel当之无愧是榜首:
章鱼喵
2018/08/02
2.2K0
2018年laravel教程第1节搭建项目phpstorm添加laravel代码提示新建路由和控制器渲染页面定义公共模板文件公共头部和底部小结
Jekyll 优化合集
  Jekyll 是一款采用 Ruby 语言编写的、非常方便简单又功能强大的静态站点生成器,适合于搭建个人博客、静态网站等。我们知道,Github Page 默认支持的也是 Jekyll,而非 Hexo、Hugo等静态站点生成器。Hexo 是用 NodeJS 语言编写的,Hugo 是用 Go 语言编写的,它们三者背后其实都有非常丰富的插件来增强它们自身,从而为用户提供一个可插拔式的个人定制功能。由于本站目前是采用 Jekyll 来搭建的,所以为了提供给读者更加高效的阅读条件,笔者在廖柯杰大佬开发的 H2O 主题的基础上做了一些功能上的增加和优化,接下来就来详细介绍一下。
zhonger
2022/10/28
2.2K0
从零开始学 Web 之 Vue.js(六)Vue的组件
在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识点,期间也会分享一些好玩的项目。现在就让我们一起进入 Web 前端学习的冒险之旅吧!
Daotin
2018/09/30
2.4K0
从零开始学 Web 之 Vue.js(六)Vue的组件
用Publish创建博客(二)——主题开发
在Swift社区中,有不少优秀的项目致力于使用Swift生成HTML:比如Vapor的Leaf[4],Point-Free的swift-html[5]等,Plot也是其中的一员。Plot最初是由John Sundell[6]编写的并作为Publish套件的一部分,它主要的关注点是Swift的静态网站HTML生成,以及创建建站所需的其他格式文档,包括RSS、podcast、Sitemap。它与Publish紧密集成但同时也作为一个独立项目存在。
东坡肘子
2022/07/28
1.3K0
用Publish创建博客(二)——主题开发
推荐阅读
相关推荐
新型web框架Astro快速构建内容网站
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验