皆さん、こんにちは。
今日は「Nuxt3:useAsyncDataの基本的な使い方」についてご紹介します。
Nuxt 3 系以降(Nuxt Bridge / Nuxt 4 などを含む)の新しいデータ取得方法として、asyncData
や fetch
が従来(Nuxt 2 系)のオプション・フックから、Composable
という仕組みに変わりました。具体的には、useAsyncData
・useFetch
といった関数を使ってデータ取得・SSR を行います。
なお、2025年2月時点で“Nuxt 4”
は公式の安定版としてまだ公開されていません。
一般的には、Nuxt 3
(Nuxt Bridge
経由で 2から3への移行などを含む)でのデータ取得方法として useAsyncData
が広く利用されています。
Nuxt 4が正式にリリースされた際も、useAsyncData
やuseFetch
をベースとしたデータ取得の流れはほぼ同様になると考えられます。
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
同様、useAsyncData
やuseFetch
を使うことでサーバーサイドレンダリング + クライアントでのデータ再利用を簡単に実現できる。 -
useAsyncData
とuseFetch
の使い分けは好みによるところが大きい。useAsyncData
で$fetch
を使う場合のほうがNuxt
独自の利便性が得られる一方、標準fetch
になじみがあればuseFetch
でもOK
。 -
Composable
によりコードの見通しやテストがしやすくなっているので、適切にキーやオプションを設定してSSR + CSR
のデータ取得を最適化する。
現時点でまだ“Nuxt 4”
は正式な情報が十分出ていない状況ですが、Nuxt 3 での useAsyncData の利用方法がそのまま応用できると考えて問題ありません。
ぜひ参考にしてみてください。
今日は以上です。
ありがとうございました。
よろしくお願いいたします。