SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

【最新Nuxtアップデート解説】Nuxtの変更点まとめ

Vueベースのフレームワーク「Nuxt 4.2」までの大きな変更点──開発ツールとデータ取得

【最新Nuxtアップデート解説】Nuxtの変更点まとめ 第1回

エラー表示の改善

 次に紹介するのは、エラー表示に関する変更点です。

エラー表示をわかりやすいものに変更

 Nuxtアプリケーションの開発段階で、エラーが発生した場合、自動でエラー画面が表示されるようになっています。そのエラー画面がバージョン3.16で改善され、スタックトレースの表示など原因追及しやすい画面に変わっています。

 これは、Nuxtに含まれているサーバエンジンであるNitroのエラー表示機能を、Youchに変更したのが原因です。こちらは、Nitroがバージョン2.11にアップデートした際の変更であり、その変更がNuxtにも影響しています。

図6:Youchを利用したわかりやすいエラー画面
図6:Youchを利用したわかりやすいエラー画面

カスタムエラーページをオーバーレイ表示

 図6のエラー画面の右下にオーバーレイ表示されているエラー画面が、バージョン4.2で改善されたものです。それまでのエラー画面は開発者にはわかりやすいものの、実際のエラー画面がどのようなものかがすぐにはわかりませんでした。特に、カスタムエラー画面を利用している場合は、エラーごとの見え方も同時に確認したいものです。

 そこで、図6の右下のように、本来のエラー画面もオーバーレイされるようになっています。このオーバーレイエラー画面はドラッグして、画面の上下左右の各辺の任意の場所に引っ付けておくことができます。

 さらに、バージョン4.3で、オーバーレイされたエラー画面を最小化できるように変更されています。オーバーレイされたエラー画面上の[×]をクリックすると「Show error page」と表示されたアイコンへと変化します。もちろん、そのアイコンをもう一度クリックすると元の表示へと戻ります。

データ取得コンポーザブルの改善

 次に紹介するのは、データ取得コンポーザブルに関する変更点です。Nuxtには、useFetch()useAsyncData()というデータ取得に関して便利なコンポーザブルがあります。

 これらのコンポーザブルに関して、3.1以降、その性能改善も含めてさまざまな変更が施されています。

リアクティブキーが利用可能

 useFetch()でも、useAsyncData()でも、ユニークキー文字列を指定でき、そのキー文字列がキャッシュの制御(識別)に利用されています。そのキー文字列として、リアクティブな変数が利用できるように、バージョン3.17で変更になっています。

 例えばリスト1のコードです(以下のコード例は、全てuseFetch()で紹介していますが、useAsyncData()でも同じです)。

[リスト1]リアクティブな変数を利用したuseFetch()のキーの例
const randomKey = ref(Math.random());
const { data } = await useFetch(
  "/api/getTimestamp", 
  {
    key: computed(
      () => {
        return "timestampWithRandomKey_" + randomKey.value;
      }
    )
  }
);

 リスト1では、キー文字列を指定するkeyオプションが算出プロパティとなっています。その中でリアクティブな変数であるrandomKeyを利用しています。

 この状態でrandomKeyの値が変更されると、自動的にキーが変わることになり、結果、キャッシュが利用されずにデータの再取得が行われます。

キャッシュの改善

 このように、キー文字列は取得したデータのキャッシュに利用されています。このキャッシュの仕組みが同じく3.17で改善され、同一キーの場合は、コンポーネントまたぎでキャッシュが利用されるようになっています。

 例えば、リスト2のデータ取得コードが書かれたページコンポーネントとしてfetchTimestampWithKey.vueがあるとします。キーとしてtimestampWithKeyを指定しています。

[リスト2]fetchTimestampWithKey.vue
const { data } = await useFetch(
  "/api/getTimestamp", 
  {
    key: "timestampWithKey"
  }
);

 そして、例えば、このページからの遷移先ページコンポーネントとして、fetchTimestampWithKeySub.vueがあるとします。そこに、リスト2と同じデータ取得コードであるリスト3が記述されているとします。ポイントは、キーがリスト2と同じtimestampWithKeyだということです。

[リスト3]fetchTimestampWithKeySub.vue
const { data } = await useFetch(
  "/api/getTimestamp", 
  {
    key: "timestampWithKey"
  }
);

 この場合、リスト3のfetchTimestampWithKey.vueが表示された後にfetchTimestampWithKeySub.vueが表示される際に、データ取得通信は行われず、同一キーであるtimestampWithKeyでキャッシュされたデータを再利用されます。この仕組みにより、余分なデータ通信を減らすことができます。

clearユーティリティの追加

 一方で、任意のタイミングでキャッシュをクリアしたい場合もあります。その際に便利なユーティリティとして、clearが、バージョン3.11で導入されています。

 例えば、リスト4のfetchTimestampWithKeySub.vueにおいて、リスト4の(1)のように、useFetch()の戻り値オブジェクトにclearプロパティを取得するコードを追記したとします。

[リスト4]fetchTimestampWithKeySub.vue
const { data, clear } = await useFetch(  // (1)
  :
);

clear();  // (2)

 その上で、リスト4の(2)のようにこのclearを任意のタイミングで関数として実行します。すると、取得したデータのキャッシュが削除されます。

 その状態で画面遷移などで、fetchTimestampWithKey.vueやfetchTimestampWithKeySub.vueの画面を再表示させると、その時点でのデータを再取得することになります。

getCachedDataの導入

 こういったキャッシュの再利用に関して、より細かい制御ができるような仕組みとして、getCachedDataオプションがバージョン3.8で導入されています。これはリスト5のようになります。

[リスト5]getCachedDataオプション利用のコード例
const { data } = await useFetch(
  "/api/getTimestamp", 
  {
    key: "timestampWithCachedController",
    getCachedData: (key, nuxtApp, ctx) => {  // (1)
      return nuxtApp.payload.data[key] || nuxtApp.static.data[key];  // (2)
    }
  }
);

 getCachedDataオプションでは、プロパティ値としてアロー関数を定義し、その引数は表3の3個となっています。

表3:getCachedDataのアロー関数の引数
引数名 内容
1 key string キー文字列
2 nuxtApp NuxtApp Nuxtアプリケーション(3.11で追加)
3 ctx AsyncDataRequestContext データリクエストの理由が格納されたオブジェクト(3.17で追加)

 第1引数のキー文字列は、useFetch()やuseAsyncData()で指定したキー文字列そのものです。

 第3引数のctxであるAsyncDataRequestContextオブジェクトには、causeプロパティが定義されており、その値として表4の文字列が格納されています。

表4:第3引数ctx.causeの値
内容
initial 初期データ取得
refresh:manual refreshユーティリティの手動実行
refresh:hook フックによるrefreshの実行
watch ウォッチャーによるデータ再取得

 戻り値はundefined、またはデータそのものです。undefinedの場合はキャッシュがないものとみなし、非同期通信によるデータの取得が行われます。一方、undefined以外がリターンされた場合はその値をキャッシュされたデータとみなし、非同期通信は行いません。

 なお、getCachedDataのアロー関数の引数は、3.8でgetCachedDataが導入された時点ではkeyのみでした。これが、バージョン3.11で第2引数のnuxtAppが、バージョン3.17で第3引数のctxが追加されています。

 このうち、第2引数のnuxtAppであるNuxtAppオブジェクトが追加されたのは、getCachedDataのアロー関数内のコードにほぼ必要なオブジェクトだからです。

 それが、リスト5の(2)のコードです。データ取得において、キャッシュされたデータはNuxtAppオブジェクト内に格納されています。それを取り出しているのが(2)です。

 具体的には、ハイドレーションにおけるキャッシュデータは、NuxtAppのpayloadプロパティに、ハイドレーションしていない場合はstaticプロパティに、第1引数のkeyをキーとして格納されています。

 そのため、一旦両方のデータを取得した上で、そのどちらかをリターンするコードとなっています。そして、両方ともが存在しない場合は、自動的に戻り値がundefinedとなり、データの取得が行われるようになります。

getCachedDataによるTTL制御

 このgetCachedDataを利用すると、より細かいキャッシュ制御が行えるようになります。

 例えば、一度取得したデータに関して、10秒間はキャッシュしたデータを利用する一方で、10秒以上経過していれば再取得するといったコードも記述可能となります。いわゆるキャッシュのTTL(Time to Live)の制御です。

 これは、リスト6のコードとなります。コメント形式で解説を記載しているので参考にしてください。

[リスト6]getCachedDataを利用したキャッシュTTLの例
const { data } = await useFetch(
  "/api/getTimestamp", 
  {
    key: "timestampWithCachedController",
    transform(input) {
      return {
        ...input,
        //transformオプションを利用してフェッチデータにその時点の日時を追加。
        fetchedAt: new Date()
      }
    },
    getCachedData: (key, nuxtApp, ctx) => {
      //キャッシュデータを取得。
      const data = nuxtApp.payload.data[key] || nuxtApp.static.data[key];
      //キャッシュデータを戻り値変数とする。
      let returnData = data;
      //キャッシュデータがundefinedでなければ…
      if(data) {
        //fetchedAtを元にDateオブジェクトをexpirationDateとして生成。
        const expirationDate = new Date(data.fetchedAt);
        //expirationDateを10秒後に設定。
        expirationDate.setTime(expirationDate.getTime() + 10000)
        //現在の日時がexpirationDateよりあとかどうかの値をisExpiredとする。
        const isExpired = expirationDate.getTime() < Date.now()
        //現在の日時がexpirationDateよりあとならば…
        if(isExpired) {
          //戻り値をundefinedに変更。
          returnData = undefined;
        }
      }
      //戻り値としてキャッシュされたデータかundefinedをリターン。
      return returnData;
    }
  }
);

まとめ

 Nuxtのバージョン4.3までの変更点をテーマごとに紹介する本連載の第1回目は、いかがでしたでしょうか。

 今回は、概説と、新しいプロジェクト構成、エラー表示の改善点、データ取得の変更点を紹介しました。

 次回は、コンポーザブルやコンポーネントに関して、新たに追加されたもの、変更されたものを紹介します。

この記事は参考になりましたか?

この記事の著者

WINGSプロジェクト 齊藤 新三(サイトウ シンゾウ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook <個人紹介>WINGSプロジェクト所属のテクニカルライター。Web系製作会社のシステム部門、SI会社を経てフリーランスとして独立。屋号はSarva(サルヴァ)。HAL大阪の非常勤講師を兼務。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/23346 2026/02/19 09:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング