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