0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Nuxt3:useAsyncDataの基本的な使い方

Posted at

皆さん、こんにちは。

今日は「Nuxt3:useAsyncDataの基本的な使い方」についてご紹介します。

Nuxt 3 系以降(Nuxt Bridge / Nuxt 4 などを含む)の新しいデータ取得方法として、asyncDatafetchが従来(Nuxt 2 系)のオプション・フックから、Composableという仕組みに変わりました。具体的には、useAsyncDatauseFetchといった関数を使ってデータ取得・SSR を行います。

なお、2025年2月時点で“Nuxt 4”は公式の安定版としてまだ公開されていません。
一般的には、Nuxt 3Nuxt Bridge経由で 2から3への移行などを含む)でのデータ取得方法として useAsyncDataが広く利用されています。
Nuxt 4が正式にリリースされた際も、useAsyncDatauseFetchをベースとしたデータ取得の流れはほぼ同様になると考えられます。

Nuxt 3 (あるいは Nuxt 4 で想定されるほぼ同等の書き方) をベースに、useAsyncData の使い方を解説します。

useAsyncData の基本的な使い方

useAsyncData は サーバーサイドでのデータ取得 (SSR) とクライアントサイドでの再利用 の両方を手軽に行える Composable です。次のような流れになります。

  • useAsyncData(key, handler, options?)の呼び出し
  • 返ってきた{ data, pending, error, refresh, ... }オブジェクトを利用してテンプレートやスクリプトで扱う
  • サーバーサイドでの初回描画時には Nuxt がデータを取得し、HTML に埋め込む
  • クライアントサイドでは埋め込まれたデータを再利用し、再度の取得を不要にする(オプションにより再度フェッチさせることも可能)

サンプルコード

<template>
  <div>
    <h1>ユーザー情報</h1>
    <!-- データが取得できたら表示 -->
    <div v-if="data">
      <p>ID: {{ data.id }}</p>
      <p>Name: {{ data.name }}</p>
    </div>

    <!-- 読み込み中の場合 -->
    <div v-else-if="pending">
      <p>Loading...</p>
    </div>

    <!-- エラーが発生した場合 -->
    <div v-else-if="error">
      <p style="color: red;">Error: {{ error.message }}</p>
    </div>

    <!-- 手動で再取得したい場合 -->
    <button @click="refresh">Refresh</button>
  </div>
</template>

<script setup>
// useAsyncData composable をインポート
// Nuxt 3 / 4 の場合はデフォルトで使えるため明示的なインポート不要の場合も
// import { useAsyncData } from '#app';

const { data, pending, error, refresh } = await useAsyncData(
  // 第1引数: キャッシュ用のキー (ユニークな文字列推奨)
  'fetchUser',
  // 第2引数: データ取得処理
  () => $fetch('/api/user')
  // 第3引数(オプション): 
  // { 
  //   // server: false にすると SSR 時にはリクエストしないなどの設定も可能
  //   // lazy: true にするとページ描画後に非同期でフェッチを行う
  // }
)
</script>
  • data: 取得したデータが返る(ref でラップされている)
  • pending: リクエストの進行状況(true なら通信中)
  • error: 何らかのエラーが発生した場合の情報(null でないならエラー発生)
  • refresh: 再度データ取得を実行するためのメソッド

useFetchとの違い

Nuxt 3/4 には同じようにデータ取得を行うuseFetchというComposableも用意されています。

  • useFetch(url, options?): fetch APIを内部的に利用
  • useAsyncData(key, handler, options?): $fetch(軽量な Fetch ラッパ) を利用

useFetchは内部的に ブラウザの標準fetchを使う点が大きな特徴で、レスポンスやエラーハンドリングなどはよりブラウザ標準に近い形で行われます。一方、$fetchにはデフォルトで credentialsやヘッダー周りの扱い、エラー処理の違いなど、Nuxt 独自の利便性が加わっています。

SSR とキャッシュ

useAsyncDataは SSR 中に取得されたデータをクライアントサイドに埋め込み、クライアント遷移時の無駄なリクエストを省く ことができます。たとえばユーザーがページ遷移して戻ってきた際にも、キャッシュ済みのデータを再利用する設定が可能です。

// options パラメータの例
const { data } = await useAsyncData('fetchUser', () => $fetch('/api/user'), {
  default: () => ({ id: 0, name: '' }), // デフォルト値
  transform: (rawData) => rawData.user, // レスポンスの整形
  watch: false, // リアクティブな値の変更で再フェッチするかどうか
  immediate: true, // 初回読み込みですぐにフェッチするか
  lazy: false, // SSR 完了後、クライアントでロード時にフェッチするか
  // ...etc
})

API ルートの例 (/api/user)

上記サンプルの'/api/user'は、サーバーサイドでデータを返すエンドポイントとして想定しています。Nuxt 3/4 ではserver/api/以下にファイルを置くだけで API ルートを定義でき、エンドポイントと SSR が同居 する形になります。

たとえばserver/api/user.tsというファイルを作って以下のようにすると、'/api/user'でアクセスできます。

export default defineEventHandler(async (event) => {
  // ここでデータベースや外部APIにアクセスしたりする
  // 一旦ダミーデータを返す
  return {
    id: 1,
    name: 'Taro Nuxt'
  }
})

まとめ

  • Nuxt 4であってもNuxt 3同様、useAsyncDatauseFetchを使うことでサーバーサイドレンダリング + クライアントでのデータ再利用を簡単に実現できる。
  • useAsyncDatauseFetchの使い分けは好みによるところが大きい。useAsyncData$fetchを使う場合のほうがNuxt独自の利便性が得られる一方、標準fetchになじみがあればuseFetchでもOK
  • Composableによりコードの見通しやテストがしやすくなっているので、適切にキーやオプションを設定して SSR + CSRのデータ取得を最適化する。

現時点でまだ“Nuxt 4”は正式な情報が十分出ていない状況ですが、Nuxt 3 での useAsyncData の利用方法がそのまま応用できると考えて問題ありません。

ぜひ参考にしてみてください。

今日は以上です。

ありがとうございました。
よろしくお願いいたします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?