はじめに
Nuxt.jsは、Webページのユーザーインタフェース(UI)フレームワークであるVue.jsに、Webページの作成に必要なUI以外の追加機能をまとめて提供するフレームワークです。
Vue.jsのコンポーネントは、dataメソッドに定義されたデータを画面に表示しますが、Nuxt.jsでは、Webページの表示前にコンポーネントのデータをネットワークから取得できる、非同期データと呼ばれる機能(asyncDataメソッド)が利用できます。asyncDataメソッドを利用すると、ネットワークからデータを取得後、その内容をページに表示できます。同様に、ページ表示前にデータを取得してVuexストアに反映する機能(fetchメソッド)も利用できます。これらのメソッドは、Nuxt.jsのページコンポーネント(pagesフォルダーに配置する、1つのWebページに対応するコンポーネント)のみで利用できます。
本記事では、asyncDataメソッドやfetchメソッドの利用法を、サンプルとともに説明します。また、asyncDataやfetch内でデータを取得するHTTP通信を行うため、Nuxt.jsで推奨されているHTTPライブラリーAxiosを利用していきます。
対象読者
- ネットワークからデータを取得して反映するWebページをNuxt.jsで作りたい方
- Vuexストアの値をネットワークから取得して設定したい方
- Nuxt.jsでAxiosの機能を使いたい方
必要な環境
本記事のサンプルコードは、以下の環境で動作を確認しています。
-
Windows 10 64bit版
- Node.js v12.16.3 64bit版
- Nuxt.js 2.12.2
- Vue.js 2.6.11
- Microsoft Edge 81.0.416.68
サンプルコードは、Nuxt.jsのCLIツール(create-nuxt-app)で生成したプロジェクトを元に実装しています。CLIツールの利用法やプロジェクト構成などの詳細は、連載第1回の記事を参照してください。
サンプルコードを実行するには、サンプルのフォルダーで「npm install」コマンドを実行してライブラリーをダウンロード後、「npm run dev」コマンドを実行して、Webブラウザーで「http://localhost:3000/」を開きます。なお、サンプルコードに含まれるAPIのプロジェクトは、「npm install」でライブラリーをダウンロード後、「npm run start」で実行できます(詳細は後述します)。
Nuxt.jsのデータと非同期データ
まず、ページコンポーネントで固定のデータを表示する単純な例(図1)を考えます。駅のコインロッカー空き状況表示を想定したページです。
ページコンポーネント(pages/index.vue)の実装はリスト1の通りです。
<template> <div class="container"> <h1>{{ name }} コインロッカー状況</h1><!--(1)--> <table> (略) <tr v-for="elem in lockerStatus" v-bind:key="elem.id"><!--(2)--> <td>{{ elem.place }}</td> <td>{{ elem.availableS ? '〇' : '×' }}</td> <td>{{ elem.availableM ? '〇' : '×' }}</td> <td>{{ elem.availableL ? '〇' : '×' }}</td> </tr> </table> </div> </template> <script> export default { data() { // データ ...(3) return { name: '北山本駅', lockerStatus: [ { id: 1, place: '南改札前', availableS: true, availableM: false, availableL: true }, (略) ] } } } </script>
表示するデータは(3)のdataメソッドに記述されます。データには、駅の名前(name)とロッカー状況の配列(lockerStatus)が含まれ、lockerStatus配列の要素には、ロッカーの場所(place)と、S/M/L各サイズのロッカー空き状況(availableS/availableM/availableL)が格納されます。これらのデータを参照して、<template>部の(1)でnameを、(2)のv-forディレクティブでlockerStatus配列の内容を表示します。
このサンプルでは、リスト1(3)に記述された固定のデータを表示しますが、Nuxt.jsの非同期データ(asyncDataメソッド)を利用すると、ページ表示前にネットワークからデータを取得してページに反映できます。
手順としてはまず、生成するNuxt.jsのプロジェクトで、Axiosを利用できるようにします。プロジェクト生成時に表示される「Choose Nuxt.js modules」のリストで「Axios」を選択すると、Axiosのモジュールがプロジェクトに組み込まれます。
生成したプロジェクトで、index.vueの<script>部をリスト2の通り実装します。<template>部はリスト1から変更ありません。
export default { asyncData({ $axios }) { // AxiosによるHTTP通信 ...(1) return $axios.get('http://localhost:3001/lockerStatus') .then(res => { // 通信後の処理 ...(2) // 通信結果をlockerStatusに設定 ...(3) return { lockerStatus: res.data } }) }, data() { return { name: '北山本駅' // data ...(4) } } }
asyncDataメソッドの引数に渡される$axiosはAxiosのオブジェクトです(後述する「引数分割束縛」で記述しています)。(1)で、引数にAPIのURLを指定して$axios.getメソッドを実行すると、HTTP GETでAPIからデータを取得するPromiseを返却します。通信処理終了後に実行されるPromiseのthenメソッド(2)で、(3)の通りレスポンスのデータをres.dataで取得してlockerStatusに設定しています。asyncDataメソッドの処理で設定されたlockerStatusは、dataメソッドに記述したname(4)のデータとマージされて、両者を区別せずに<template>部で参照できます。
なお、リスト2のasyncDataメソッドは、async/awaitを利用して、リスト3の通り記述することもできます。
async asyncData({ $axios }) { const res = await $axios.get('http://localhost:3001/lockerStatus') return { lockerStatus: res.data } }
[補足]パラメーターの「引数分割束縛」とコンテキスト
リスト2(1)で「asyncData({ $axios })」と、パラメーターを中カッコで囲んでいるのは、前回記事でも紹介した「引数分割束縛」の記法です。この記法では、中カッコ内のプロパティを引数から取り出してメソッド内で利用できるようになります。例えば、リスト4の(1)と(2)は同じ処理です。
// 引数分割束縛を利用する場合 ...(1) asyncData({ $axios }) { // 引数の$axiosプロパティを取り出して関数内で利用 return $axios.get('http://localhost:3001/lockerStatus') (以下略) } // 引数分割束縛を利用しない場合 ...(2) asyncData(context) { // 引数contextの$axiosプロパティを直接利用 return context.$axios.get('http://localhost:3001/lockerStatus') (以下略) }
asyncDataメソッドの引数(コンテキスト)には、Axiosのオブジェクトなど、フレームワークから提供されるオブジェクトやパラメーターが設定されます。詳細は後述します。
[補足]データを提供するAPIのプロジェクト
リスト2(1)のAPI呼び出しは、リスト1(3)のlockerStatus配列に相当する、リスト5のJSON文字列がAPIから返却されることを想定しています。
[ { "id": 1, "place": "南改札前", "availableS": true, "availableM": false, "availableL": true }, (略) ]
サンプルコードには、リスト5のJSON文字列を返却するAPIのプロジェクト(p002-api-mock)を含めています。このプロジェクトを「npm run start」コマンドで実行してから、APIのURL「http://localhost:3001/lockerStatus」にアクセスすると、リスト5の内容が返却されることを確認できます。リスト2のプロジェクト(p002-asyncdata)を実行するときは、まずこのプロジェクトを実行して、APIが利用できるようにしてください。
なお、APIのプロジェクトでは、開発用の簡易的なAPIを実装できるjson-serverライブラリーを利用しています。json-serverを利用すると、HTTP GETによるデータ取得や、POSTによるデータ更新が実装できます。詳細はサンプルコードを参照してください。