16
Re:Nuxt 100 天練習曲
Day 16

開始點餐吧! (useFetch 實戰)

Day 16·useFetch·實際應用

使用 useFetch 就像在餐廳裡對服務生說:「我要一份今日特餐」。Nuxt 會自動幫您處理好點餐、等餐、上菜、以及打包「外帶餐盒 (Payload)」的所有流程。

1. 您的第一個 useFetch

假設我們要從一個公開的 API https://jsonplaceholder.typicode.com/posts 獲取文章列表。

在頁面中,我們只需要一行關鍵的程式碼:

pages/posts.vue
<script setup>
// 向 API 發出請求,並解構出回傳的資料
const { data: posts, pending, error } = await useFetch('https://jsonplaceholder.typicode.com/posts');
</script>

<template>
  <div>
    <h1>文章列表</h1>

    <div v-if="pending">
      正在載入中...
    </div>

    <ul v-else-if="posts">
      <li v-for="post in posts.slice(0, 5)" :key="post.id">
        {{ post.title }}
      </li>
    </ul>

    <div v-else-if="error">
      糟糕,出錯了:{{ error.message }}
    </div>
  </div>
</template>

2. 解讀回傳的資訊 (訂單狀態)

useFetch 會回傳一個物件,裡面包含了所有您需要的資訊,其中最重要的是這幾個:

data: 餐點本人

API 成功回傳的資料,會被裝在這個 ref 裡。

pending: 等餐狀態

這是一個布林值 (true/false) ref,告訴我們「是不是還在等資料回來?」。在等待時,我們可以顯示一個「載入中...」的訊息,提升使用者體驗。

error: 送錯餐了

如果請求失敗,錯誤訊息會被放在這裡。我們可以根據它來顯示錯誤提示。

refresh: 再來一份!

這是一個函式。當您呼叫 refresh() 時,Nuxt 會重新去請求一次資料。非常適合用在「更新」按鈕上。

3. 兩個實用的進階技巧

技巧一:不用等餐,先進餐廳 (lazy)

預設情況下,Nuxt 會等資料都拿到手才顯示頁面。但有時我們希望使用者能「先進來坐,餐點慢慢上」,讓頁面切換感覺更快。

這時可以使用 lazy 選項,或是直接使用它的簡便寫法 useLazyFetch

使用 lazy 選項
// 啟用 lazy,頁面會立刻顯示,但 posts 一開始會是 null
const { data: posts, pending } = useLazyFetch('https://jsonplaceholder.typicode.com/posts');

注意:使用 lazy 時,您必須要處理 pending 狀態,否則使用者會先看到一片空白。

技巧二:我只想要薯條 (pick)

有時候 API 回傳的資料包山包海,但您其實只需要其中一兩個欄位。使用 pick 選項,可以告訴 Nuxt:「我只想要這幾樣東西,其他的不用打包進行李箱 (Payload)」。

這能有效減少從伺服器傳到客戶端的資料量,讓網站更快。

使用 pick 選項
// 假設 API 回傳 { id, title, body, userId }
// 我們告訴 Nuxt,我們只需要 id 和 title
const { data: posts } = await useFetch('...', {
  pick: ['id', 'title']
})

今日總結

今天我們實際操作了 useFetch,從發出請求、處理載入中/錯誤狀態,到使用 lazy 和 pick 進行優化。您現在已經掌握了 Nuxt 中最核心的資料獲取技能!

預告:useFetch 能應付大多數情況,但如果我們的資料來源不是簡單的網址,或者我們只想在使用者點擊按鈕後才去要資料呢?明天,我們將來學習另外兩位好夥伴:$fetch 和 useAsyncData 的使用時機。