VueJS 速習チュートリアル

Vue HTTP リクエスト

HTTPリクエスト(HTTP request)は、クライアントとサーバー間の通信の一部です。
クライアントがサーバーにHTTPリクエストを送信し、サーバーはそのリクエストを処理してHTTPレスポンスを返します。

1. HTTP について

HTTPHyper Text Transfer Protocol の略称です。

ブラウザでインターネットを閲覧しているとき、バックグラウンドでは常にHTTPリクエストが行われています。ページにアクセスすると、ブラウザ(クライアント)はサーバーに対して複数のHTTPリクエストを送信し、サーバーは必要なファイルやデータをHTTPレスポンスとして返します。

代表的なHTTPリクエストメソッドには以下のようなものがあります:

  • GET: データの取得
  • POST: データの作成
  • PUT / PATCH: データの更新
  • DELETE: データの削除

2. 'fetch' メソッド

Vueでサーバーからデータを取得するには、JavaScript標準の fetch() メソッドを使用できます。

このチュートリアルで fetch() を使用する際、特にメソッドを指定しない場合は、バックグラウンドでデフォルトの GET メソッドが使用されます。
fetch() メソッドは、データの取得先となるURLを引数として受け取ります。

以下は、fetch() を使用してHTTP GETリクエストを送信し、ローカルファイル file.txt 内のテキストデータを受け取る簡単な例です。

2.1 基本的な fetch の使用(Promiseの理解)

App.vue:

<template>
  <div>
    <button @click="fetchData">データを取得</button>
    <p v-if="data">{{ data }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      data: null,
    };
  },
  methods: {
    fetchData() {
      const response = fetch("file.txt");
      this.data = response;
    }
  }
};
</script>

上記の例では、結果として [object Promise] と表示されるだけで、期待したテキストは得られません。
これは、fetch()プロミス(Promise) ベースのメソッドであり、プロミスオブジェクトを返すためです。最初の戻り値は「リクエストが送信された」という状態を示すオブジェクト(pending 状態)に過ぎません。

データが実際に取得されたとき、プロミスは fulfilled(完了)状態になります。この完了を待ってデータを取得するには、fetch() の前に await 演算子を使用する必要があります。

また、メソッド内で await を使用する場合、そのメソッド自体に async 演算子を付与しなければなりません。

async fetchData() {
  const response = await fetch("file.txt");
  this.data = response;
}

async はそのメソッドが非同期(Asynchronous)であることをブラウザに伝えます。これにより、ブラウザは完了を待つ間、他のタスクを並行して実行できるようになります。この状態では単なる「Promise」ではなく「Response」オブジェクトが得られ、データ取得まであと一歩の状態になります。

2.2 テキストデータの取得

file.txt 内のテキストを取得するには、レスポンスに対して .text() メソッドを使用します。この .text() もプロミスを返すため、await が必要です。

App.vue:

<template>
  <div>
    <button @click="fetchData">データを取得</button>
    <p v-if="data">{{ data }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      data: null,
    };
  },
  methods: {
    async fetchData() {
      const response = await fetch("file.txt");
      // レスポンスからテキストを抽出して待機
      this.data = await response.text();
    }
  }
};
</script>

3. JSON ファイルからのデータ取得

実務では、データの保存形式として JSON(JavaScript Object Notation) がよく使われます。JSONは人間にも読みやすく、多くのプログラミング言語でサポートされているため、特定のデータを抽出するのに適しています。

JSONファイルを読み込む場合、.text() の代わりに .json() メソッドを使用します。これにより、レスポンスがJavaScriptオブジェクトとして解析されます。

3.1 JSON データのパース

App.vue:

<template>
  <div>
    <button @click="fetchData">データを取得</button>
    <pre v-if="data">{{ data }}</pre>
  </div>
</template>

<script>
export default {
  data() {
    return {
      data: null,
    };
  },
  methods: {
    async fetchData() {
      const response = await fetch("bigLandMammals.json");
      this.data = await response.json();
    }
  }
};
</script>

3.2 取得したオブジェクトの活用

.json() の結果はオブジェクトであるため、特定のプロパティにアクセスできます。以下の例では、取得したリストからランダムに1頭の動物を表示しています。

App.vue:

<template>
  <p>ボタンを何度かクリックして、ランダムに選ばれる動物を確認してください。</p>
  <button @click="fetchData">データを取得</button>
  <div v-if="randomMammal">
    <h2>{{ randomMammal.name }}</h2>
    <p>最大体重: {{ randomMammal.maxWeight }} kg</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      randomMammal: null
    };
  },
  methods: {
    async fetchData() {
      const response = await fetch("bigLandMammals.json");
      const data = await response.json();
      // ランダムなインデックスを生成
      const randIndex = Math.floor(Math.random() * data.results.length);
      this.randomMammal = data.results[randIndex];
    }
  }
};
</script>

4. API からのデータ取得

API(Application Programming Interface)を利用することで、天気予報や株価などのリアルタイムデータを取得できます。APIを呼び出した際のレスポンスの多くはJSON形式です。

4.1 外部APIとの連携例

random-data-api.com を利用して、ランダムなユーザー情報を取得してみましょう。

App.vue:

<template>
  <h1>実装例</h1>
  <p>ボタンをクリックしてHTTPリクエストでデータを取得します。</p>
  <p>クリックするたびに、ランダムなユーザーオブジェクトが生成されます。</p>
  <button @click="fetchData">データを取得</button>
  <pre v-if="data">{{ data }}</pre>
</template>

<script>
  export default {
    data() {
      return {
        data: null,
      };
    },
    methods: {
      async fetchData() {      
        const response = await fetch("https://random-data-api.com/api/v2/users"); 
        this.data = await response.json();
      }   
    }
  };
</script>

4.2 ユーザーインターフェース(UI)の構築

取得したデータをより分かりやすく、アバター画像や職種と共に表示するように改良します。

App.vue:

<template>
  <h1>実装例</h1>
  <p>ボタンをクリックしてHTTPリクエストでデータを取得します。</p>
  <button @click="fetchData">データを取得</button>
  <div v-if="data" id="dataDiv">
    <img :src="data.avatar" alt="アバター">
    <pre>{{ data.first_name + " " + data.last_name }}</pre>
    <p>"{{ data.employment.title }}"</p>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        data: null,
      };
    },
    methods: {
      async fetchData() {      
        const response = await fetch("https://random-data-api.com/api/v2/users"); 
        this.data = await response.json();
      },    
    }
  };
</script>

<style>
#dataDiv {
  width: 240px;
  background-color: aquamarine;
  border: solid black 1px;
  margin-top: 10px;
  padding: 10px;
}
#dataDiv > img {
  width: 100%;
}
pre {
  font-size: larger;
  font-weight: bold;
}
</style>

5. 'axios' ライブラリの利用

JavaScriptライブラリである Axios を使用しても、同様にHTTPリクエストを行うことができます。Axiosは古いブラウザのサポートや自動的なJSONパースなど、fetchよりも多機能な面があります。

まず、プロジェクトのフォルダで以下のコマンドを実行してインストールします:
npm install axios

5.1 Axios による実装例

App.vue:

<template>
  <h1>実装例(Axios)</h1>
  <p>ボタンをクリックしてHTTPリクエストでデータを取得します。</p>
  <button @click="fetchData">データを取得</button>
  <div v-if="data" id="dataDiv">
    <img :src="data.data.avatar" alt="アバター">
    <pre>{{ data.data.first_name + " " + data.data.last_name }}</pre>
    <p>"{{ data.data.employment.title }}"</p>
  </div>
</template>

<script>
  import axios from 'axios'

  export default {
    data() {
      return {
        data: null,
      };
    },
    methods: {
      async fetchData() {      
        // axios.get() を使用
        this.data = await axios.get("https://random-data-api.com/api/v2/users");
      }
    }
  };
</script>

<style>
/* スタイルは前述の例と同様 */
#dataDiv {
  width: 240px;
  background-color: aquamarine;
  border: solid black 1px;
  margin-top: 10px;
  padding: 10px;
}
#dataDiv > img {
  width: 100%;
}
pre {
  font-size: larger;
  font-weight: bold;
}
</style>

これで、Vue.jsにおける基本的なデータ取得の流れをマスターできました。アプリケーションの要件に合わせて、標準の fetch か、より高機能な Axios かを選択しましょう。