聊聊在 Svelte 獲取數(shù)據(jù)的小技巧
本教程探討如何在 Svelte 應用程序中的使用和呈現(xiàn)來自 API 的數(shù)據(jù)。您可以使用 Axios、Apisauce、JavaScript 的原因 Fetch API 或您選擇的任何 HTTP 客戶端在生命周期掛鉤中與 Svelte 中的 API 進行交互。
我們將構建一個示例應用程序來交互和顯示由 REST API 服務器提供的數(shù)據(jù)。此應用程序?qū)⒃试S用戶從 REST API 獲取博客文章列表并將其顯示在頁面上。
先決條件
為了學習本教程,您需要具備一些知識 JavaScript 和 CSS 的先驗知識,以及對Svelte的一些熟悉。
您還需要在您的機器上安裝Node 和 npm以及Git。
什么是 REST API?
首字母縮略詞 API 代表“應用程序編程接口”,簡單來說,它是兩個應用程序通信或相互共享數(shù)據(jù)的一種方式。
REST API 是一種實現(xiàn)代表性狀態(tài)傳輸 (REST) 協(xié)議的 API。REST 是一種用于構建通過 HTTP 協(xié)議交互的 Web 服務的架構風格。REST 的請求結構包括四個基本部分,分別是 HTTP 方法、端點、標頭和請求正文。
HTTP 方法
API 請求中的 HTTP 方法告訴服務器客戶端期望它執(zhí)行什么樣的操作。當今最廣泛使用的是 HTTP 方法包括 GET、POST、PATCH、DELETE,下面將對其進行簡要說明。
- GET:用于從服務器獲取或讀取信息。
- POST:用于在服務器中創(chuàng)建或存儲記錄。
- PUT/ PATCH:用于更新或修補服務器中的記錄。
- DELETE:用于從一個資源點刪除一條或多條記錄。
HTTP 端點
基本術語中的 HTTP 端點是一個地址或 URL,它指定 API 可以在何處訪問一個或多個資源。
HTTP 標頭
HTTP 標頭是鍵值對,允許客戶端在請求中將信息傳遞給服務器,反之亦然。
請求正文
API 調(diào)用的主體是從客戶端發(fā)送到服務器的有效負載(或數(shù)據(jù))。
設置我們的 Svelte 應用程序
我們將構建一個與外部 REST API 交互以從服務器獲取博客文章列表的示例應用程序。然后,我們將在 Svelte 客戶端上顯示此列表。
在本教程中,我們不會深入探討 Svelte 應用程序的捆綁和基礎架構,因此我們將按照Svelte 官方網(wǎng)站上的說明來啟動和運行應用程序。
在您的首選目錄中,運行:
npx degit sveltejs/template svelte-demo-app
然后,進入文件夾,使用 npm 安裝所需的依賴項并啟動開發(fā)服務器:
cd svelte-demo-app
npm install
npm run dev --open
您現(xiàn)在應該會看到“Hello, World!” 在瀏覽器中顯示的消息http://localhost:5000/。
使用 Fetch API 使用 REST API
在本文中,我們將研究從 API 獲取數(shù)據(jù)的兩種方法。首先,我們將了解如何使用 JavaScript 原生的 Fetch API。然后在下一節(jié)中,我們將看看使用 Axios 客戶端,然后簡要比較和對比這兩種方法。
什么是獲取 API?
Fetch API 是一種基于 Promise 的機制,允許您向 JavaScript 中的端點發(fā)出異步 API 請求。如果您熟悉該XMLHttpRequest()方法,您可能會同意 Fetch API 是一種改進——從某種意義上說,它提供了額外的功能,例如數(shù)據(jù)緩存、讀取流響應的能力等等。
使用 Fetch API 就像使用fetch()您要獲取的資源的路徑作為必需參數(shù)調(diào)用方法一樣簡單。例如:
const response = fetch('your-api-url.com/endpoint');
在請求中傳遞更多參數(shù)
該fetch()方法還允許您通過將init對象作為可選的第二個參數(shù)傳遞來更具體地處理您正在發(fā)出的請求。
該init對象允許您在請求中傳遞額外的詳細信息。其中最常見的如下所列:
- method: 一個字符串,它指定發(fā)送到服務器的 HTTP 方法,可以是 GET、POST、PUT、PATCH 或 DELETE 之一。
- cache:一個字符串,指定是否應緩存請求。允許的選項是default, no-cache, reload, force-cache, only-if-cached。
- headers: 用于設置與請求示例一起傳遞的標頭的對象。
- body: 中最常用的對象POST,PUT或PATCH請求。它允許您將有效負載傳遞給服務器。
構建App組件
完成 Svelte 腳手架后,打開src文件夾并找到App.svelte組件。這是您訪問項目主頁時呈現(xiàn)的內(nèi)容。
如您所見,該組件包含一個<script>用于我們的 JavaScript 的<style>塊、一個用于我們的樣式地塊,以及一個<main>帶有我們標記的標簽。這是 Svelte 組件的基本結構。
讓我們首先從 Svelte 導入onMount鉤子,如下所示:
import { onMount } from "svelte";
Svelte 中的onMount鉤子是一種生命周期方法,用于定義在使用它的組件第一次在 DOM 樹中呈現(xiàn)時應該執(zhí)行的指令。
如果您來自 React 背景,您應該注意到Svelte 中的鉤子與基于類的 React 組件中的方法或React 函數(shù)式組件中的鉤子onMount類似。componentDidMount()useEffect()。
接下來,我們將定義一個變量來保存我們打算使用的端點的 URL:
const endpoint = "https://jsonplaceholder.typicode.com/posts";
注意:JSONPlaceholder是一個方便、免費的在線 REST API,您可以在需要一些假數(shù)據(jù)時使用它。
接下來,創(chuàng)建一個posts變量并為其分配一個空數(shù)組:
let posts = [];
一旦我們進行調(diào)用,這個空posts數(shù)組將被我們從 API 接收到的數(shù)據(jù)填充。
最后,我們現(xiàn)在可以使用該onMount()方法GET使用 JavaScript 的 Fetch API 向端點發(fā)出請求,如下所示:
onMount(async function () {
const response = await fetch(endpoint);
const data = await response.json();
console.log(data);
});
拼湊在一起時,您的App組件應包含以下內(nèi)容:
<script>
import { onMount } from "svelte";
const endpoint = "https://jsonplaceholder.typicode.com/posts";
let posts = [];
onMount(async function () {
const response = await fetch(endpoint);
const data = await response.json();
console.log(data);
});
export let name;
</script>
<main>
<h1>Hello {name}!</h1>
<p>Visit the <a href="https://svelte.dev/tutorial">Svelte tutorial</a> to learn how to build Svelte apps.</p>
</main>
<style>
/* ommitted for brevity */
</style>
要檢查它是否正常工作,請保存文件,然后訪問http://localhost:3000/并檢查瀏覽器的開發(fā)工具。您應該會看到記錄到控制臺的一組對象。
注意:如果您想知道該export let name;聲明,這就是我們在 Svelte 中定義道具的方式。此處的export關鍵字聲明此值是組件的父級將提供的道具。
顯示來自端點的數(shù)據(jù)
現(xiàn)在我們已經(jīng)能夠成功地從端點提取數(shù)據(jù),是時候在我們的頁面上呈現(xiàn)內(nèi)容了。我們可以使用each 塊來做到這一點:
{#each posts as article}
<div>
<p>{article.title}</p>
</div>
{/each}
將標記更改App.svelte為以下內(nèi)容:
<main>
<h1>Hello {name}!</h1>
<p>Visit the <a href="https://svelte.dev/tutorial">Svelte tutorial</a> to learn how to build Svelte apps.</p>
{#each posts as article}
<div>
<p>{article.title}</p>
</div>
{/each}
</main>
然后將以下行添加到腳本塊:
posts = data;
您現(xiàn)在應該會看到呈現(xiàn)到頁面的帖子標題列表。
使用 Axios 客戶端使用 REST API
Axios是一個開源的、基于 Promise 的 JavaScript 庫,用于進行與 Fetch API 非常相似的 API 調(diào)用。Axios 提供了一些特定的方法來執(zhí)行各種 API 請求。例如:
- axios.get()用于向端點發(fā)出 GET http 請求。
- axios.post()用于在創(chuàng)建記錄時發(fā)出 POST 請求。
- 當您需要發(fā)出 HTTP 請求以更新 API 中的記錄時,可以使用axios.patch()和axios.put()。
- axios.delete()用于向端點發(fā)送 HTTP DELETE 請求。
安裝 Axios 并更新App組件
要在我們的項目中使用 Axios,我們首先需要安裝它。在項目根目錄中,運行:
npm i axios@0.21.1
注意:我在這里安裝了一個稍舊的版本,因為該庫的最新版本引入了一個錯誤,這會導致在TypeError: Cannot convert undefined or null to objectSvelte 組件中使用 Axios 時出錯。見這里和這里。希望這將由庫的未來版本修復。
然后,在App組件中,包含庫:
import axios from "axios";
還可以像這樣更改onMount鉤子中的代碼:
onMount(async function () {
const response = await axios.get(endpoint);
console.log(response.data);
posts = response.data;
});
您應該會在瀏覽器中看到與之前相同的結果。
錯誤處理
由于 Ajax 請求是在異步函數(shù)中發(fā)出的,我們需要使用一個try … catch塊來報告任何錯誤:
onMount(async function () {
try {
const response = await axios.get(endpoint);
console.log(response.data);
posts = response.data;
} catch (error) {
console.error(error);
}
});
這不是 Axios 獨有的。在使用 Fetch API 時,您將應用相同的方法。
Axios 中的分組請求
Axios 的一個不錯的功能是您可以使用該axios.all()方法同時向多個端點發(fā)出 HTTP 請求。此方法將一組請求作為一個數(shù)組接收,并返回一個單一的 Promise 對象,該對象僅在傳入的數(shù)組的請求已被單獨解析時才解析。
執(zhí)行此操作的語法如下面的代碼片段所示:
axios.all([
axios.get("https://jsonplaceholder.typicode.com/posts"),
axios.get("https://jsonplaceholder.typicode.com/comments"),
])
.then((responseArr) => {
//this will be executed only when all requests are complete
console.log("First Post: ", responseArr[0].data[0].title);
console.log("Second Comment: ", responseArr[1].data[1].body);
})
.catch((error) => {
console.log(error);
});
在這里(為了變化)我鏈接了使用then()和使用的方法catch()來處理錯誤。
Axios 與 Fetch
與 相比fetch(),Axios 附帶了一些額外的附加功能,例如:
- 請求和響應攔截。
- 更好的簡化錯誤處理過程。
- XSRF 保護。
- 上傳進度支持。
- 響應超時。
- 取消請求的能力。
- 支持舊版瀏覽器。
- 自動 JSON 數(shù)據(jù)轉(zhuǎn)換。
此外,Axios 可以在瀏覽器和 Node.js 中使用。這有助于在瀏覽器和后端之間共享 JavaScript 代碼或?qū)η岸藨贸绦蜻M行服務器端渲染。
您可以在此處了解一些進一步的差異。
結論
我們在本次演練中介紹了很多內(nèi)容。我們首先要了解什么是 REST API,以及為什么您可能希望在應用程序中使用外部服務。onMount然后我們建立了一個 Svelte 項目并使用 Fetch API 從一個使用 Svelte方法的虛擬 API 中間提取文章列表。最后,我們查看了一下 Axios HTTP 庫,然后重寫了我們的腳本以使用 Axios 而不是 Fetch API 使用我們的模擬 API。