從零開始使用 Astro 的實用指南

chuck發表於2023-05-18

在這個實用的Astro指南中,我將指導你完成設定過程,並告訴你如何構造你的檔案。你將學習如何新增頁面、互動式元件,甚至是markdown文章。我還會告訴你如何從伺服器上獲取資料,建立佈局,並使用vanilla JavaScript和其他框架新增互動性。準備好享受一些動手的樂趣,因為我們將一起建立一個小型的網站例項。我們將構建一個多頁面的網站,包括一個部落格。

在這篇文章末尾,你會很好地理解Astro是如何工作的,以及你如何使用它來更快地建立高效的網站。開始吧!

  • 什麼是Astro框架?
  • Astro入門
  • Astro專案結構
  • Astro頁面
  • Astro元件
  • 新增指令碼
  • Astro佈局
  • <slot />元素
  • 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的小型對話:

image.png

一旦你在編輯器中開啟你的專案,你可以安裝Astro的擴充套件。由於Astro有自己的檔案擴充套件和語法,你可能想為你的編輯器安裝其擴充套件。這裡是VSCode的Astro擴充套件的連結,它不僅僅為你高亮語法,還能做得更多。

現在你可以用以下命令來執行你的專案。不需要安裝任何依賴。

npm run dev

開啟瀏覽器,訪問http://localhost:3000/ ,一切就緒。

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,並在裡面寫上非常簡單的標記語言:

<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的內容複製貼上到該檔案中:

image.png

你剛剛完成了你的第一個Astro佈局,現在你需要在你的Astro頁面中使用它。讓我們看看你如何能做到這一點。

像元件一樣,第一步是將佈局匯入到程式碼柵欄,然後透過在模板部分放置其標籤來使用它。下面就是index.astro的樣子:

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

如果你試圖為你的About頁面做同樣的事情,你會注意到about.astro裡面有不同的內容。你需要保留它,或者以某種方式將它傳遞給你的BaseLayout檔案。這就是<slot />的用武之地。

<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檔案中,並在專案中作為全域性樣式匯入。

image.png

下面是你如何將外部的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>

主頁看起來長這樣:

image.png

點選這裡檢視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新增樣式後的結果:

image.png

點選這裡檢視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內容新增到其中:

image.png

由於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>

現在頁面看起來長這樣:

image.png

我們需要做的最後一件事是在我們的主頁上顯示這些文章。

載入本地檔案

在你的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新增一些樣式後,頁面看起來是這樣的:

image.png

如果你點選”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>

下面是最終效果:

image.png

如果你在瀏覽器中進行檢視,你會注意到該元件已經在你的頁面上呈現了。然而它沒有任何可互動性。由於動作不生效,當你點選按鈕時,你無法展開子項。

我將在下一節向你展示我們需要的東西。

指令

正如你在上一個例子中看到的,這個元件被新增到了頁面上,但它沒有生效。發生這種情況是因為,預設情況下,你的框架元件只會在服務端渲染為靜態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。這樣一來,我們的使用者就有了快速、無縫的體驗,而我們仍然可以享受到使用動態框架工作的所有好處。這對使用者和開發者來說是一個雙贏的局面!

以上就是本文的全部內容,如果對你有所幫助,歡迎點贊、收藏、轉發~

相關文章