在這個實用的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.astro
和about.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。我給我的Home
和About
頁面新增了一些靜態內容,並寫了一些樣式。
下面是我新增到我的主頁的內容:
---
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 & 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.jsx
和FAQ.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。這樣一來,我們的使用者就有了快速、無縫的體驗,而我們仍然可以享受到使用動態框架工作的所有好處。這對使用者和開發者來說是一個雙贏的局面!
以上就是本文的全部內容,如果對你有所幫助,歡迎點贊、收藏、轉發~