Vuex、Pinia、 AxiosでAPIを使用する

アプリケーションプログラミングインターフェイス(API)は、アプリケーションにアクセスするためのプログラミング標準のセットです。これは、APIを使用すると、バックエンドアプリケーションとフロントエンドアプリケーションがユーザーの知識がなくても相互に通信できることを意味します。

APIの「消費」とは、APIを介してリクエストを受信し、レスポンスを送信することを意味します。この記事では、Vuex、Pinia、およびAxiosを使用してサーバーからAPIを使用する方法を学習します。 

VueでのAxiosの使用

Angular、JQuery、Vue.jsのバージョン1.0などの一部のフレームワークには、HTTPAPIが組み込まれています。Vue 2.0以降、開発者は、組み込みのHTTPクライアントモジュールであるVue-resourceは必須ではなくなり、サードパーティのライブラリに置き換えることができると判断しました。現在、最も推奨されるライブラリはAxiosです。

Axiosは柔軟なHTTPクライアントライブラリであり、デフォルトでPromiseを使用し、クライアントとサーバーの両方で実行されるため、サーバー側のレンダリング中にデータをフェッチするのに適しています。Vue.jsで簡単に使用できます。

Vuexとは何ですか?

深くネストされたコンポーネントの場合、小道具を渡すのは難しいか、ほとんど不可能です。親/子インスタンスへの直接参照を使用したり、イベントを介して状態の複数のコピーを変更および同期しようとしたりするのは魅力的です。ただし、これらのオプションはどちらも、保守不可能なコードやバグを生成する可能性があるため、お勧めしません。

Vuexは、Vue.jsアプリケーション用の状態管理パターンおよびライブラリです。これは、アプリケーション内のすべてのコンポーネントの集中ストアとして機能します。

Vuexの状態管理は、ミューテーション、状態、ゲッター、コンポーネント、およびアクションを循環します

ピニアとは?

Vuexと同様に、PiniaはVueフレームワークで動作するように設計されたもう1つの状態管理ライブラリです。Piniaの基本的な概念と原則のいくつかは、Vuexのものと非常に似ており、すぐに使用できるモジュール性や構文のわずかな違いなど、これらのライブラリを区別する概念はごくわずかです。Vuexの十分な知識があれば、Piniaの使い方を学ぶことは、始めたばかりの場合は簡単な切り替えになるはずです。

コンポジションAPIとVue3を念頭に置いて構築されているにもかかわらず、Piniaは、コンポジションAPIとオプションAPIのどちらを使用する場合でも、Vueバージョン2と3の両方で動作します。

状態管理がどのように機能するかを理解する

状態管理は、特定のアプリケーションのさまざまなコンポーネント間で共有されるデータを管理するためのデザインパターンの実装であり、ユーザーに提示されるデータ全体の一貫性を確保するのに役立ちます。

Vue.jsシングルページアプリケーション(SPA)では、複数のコンポーネントがいつでもデータを操作して変更してから、サーバーに送り返すことができます。したがって、開発者はこれらの変更を管理する方法、つまり「状態」を必要とします。これは、VuexやPiniaなどの状態管理ライブラリを使用して実行できます。

状態管理ライブラリを使用すると、コンポーネントから共有状態を抽出し、グローバルシングルトンで管理し、ツリー内のどこにいても、コンポーネントに状態へのアクセスを提供するか、アクションをトリガーできます。

状態管理ライブラリを使用する場合

大規模なSPAを構築したことがない場合、状態管理にライブラリを使用することは、複雑すぎて不要だと感じるかもしれません。ただし、中規模から大規模のSPAを構築している場合は、コンポーネント間で状態をより適切に処理および共有する方法について2度考えさせられる状況に遭遇した可能性があります。もしそうなら、VuexまたはPiniaはあなたにぴったりのツールです!

状態管理ライブラリを使用する理由

通常、次の理由から、ライブラリを使用して状態を管理する必要があります。

  • コンポーネントは状態を共有および更新する必要があります
  • これらは、データ/状態の信頼できる唯一の情報源を提供します
  • 状態管理を使用している場合、1つのコンポーネントから複数のコンポーネントにイベントを渡す必要はありません。
  • グローバル状態はリアクティブです。つまり、状態を変更すると、それを使用する他のすべてのコンポーネントで更新できます。

Axiosを使用して新しいVueプロジェクトを設定します

このチュートリアルでは、最新のデフォルトのVueバージョンである3.0とCompositionAPIを使用します。Vue CLIをまだインストールしていない場合は、ターミナルで次のコマンドを実行します。

npm install -g @vue/cli

Vue CLIがシステムにすでにインストールされているかどうかを確認するには、以下のコードを実行します。Vueがすでにインストールされている場合は、VueCLIバージョンが表示されます。

vue --version
// 5.0.1

次に、ターミナルで次のコードを実行して、Vueプロジェクトを作成します。

/** if you want to create the vue project in the folder you
are currently on, use this code**/
vue create .

/**if you want to create a new folder for your vue app,
you should use this code**/
vue create my-app

次に、Vueバージョンを選択するためのプロンプトが表示されます。Vue3を選択します。

アプリの準備ができたら、コマンドに従ってアプリディレクトリに移動し、サーバーを起動します。

Axiosをインストールしてセットアップする

次のコードを使用して、APIからデータをフェッチするために使用するAxiosをインストールしてセットアップできます。

# Using yarn
yarn add axios
# Using npm
npm install axios

Vuexストアをインストールしてセットアップする

次のコードを使用してVuexをインストールおよびセットアップします。

# Using yarn
yarn add vuex
# Using npm
npm install vuex

次に、フォルダ内にフォルダを作成し、src名前を付けますstorestoreフォルダにファイルを作成し、名前を付けますindex.js

├── index.html
└── src
    ├── components
    ├── App.vue
    └──store
       └── index.js        # where we assemble modules and export the store

次に、store/index.jsファイルに次のコードを入力します。

//import the createStore object from Vuex
import { createStore } from 'vuex'
// Import axios to make HTTP requests
import axios from "axios"
export default createStore({
    state: {},
    getters: {},
    actions: {},
    mutations: {}
})
/** we have just created a boiler plate for our vuex store module**/

main.js次のコードをファイルに追加して、ストアを登録します。

import { createApp } from 'vue'
import App from './App.vue'
//Add the line below to the file
import store from "./store";


createApp(App)
//Add the line below to the file
.use(store)
.mount('#app')

//other lines have already been added to your main.js file by default

Piniaストアをインストールしてセットアップする

Piniaをインストールしてセットアップするには、以下の手順に従います。

# First install the package
yarn add pinia
# or with npm
npm install pinia

次に、アプリのルートファイルであるファイルにPiniaをインポートし、次のmain.jsようにインスタンス化します。

import { createApp } from 'vue'
import App from './App.vue'

//Import Pinia into your config file
import { createPinia } from 'pinia'

createApp(App)
//Add the line below to the file to instantiate it
.use(createPinia())
.mount('#app')

次に、storesフォルダのルートにフォルダを作成し、。srcという名前のファイルを追加しますusers.js

// stores/users.js
import { defineStore } from 'pinia'
// Import axios to make HTTP requests
import axios from "axios"

export const useUserStore = defineStore("user",{
    state: () => ({}),
    getters: {},
    actions: {},
})

VuexストアとPiniaストアの両方を正常にセットアップしました。それでは、ストアを使用してAPIからデータをフェッチし、テンプレートにデータを入力してみましょう。

VuexとAxiosでAPIを使用する

先に進む前に、Vuexのアクション、ミューテーション、ゲッターについて詳しく知りたい場合は、LogRocketのこのテーマに関する非常に簡潔な記事を確認することをお勧めします。

Vuexストアを作成し、Vuexアクション、状態、ミューテーション、ゲッターを使用してAxiosでAPIを使用する方法を正しく理解するために、偽のJSONバックエンドからユーザー情報を取得してテンプレートに入力する単純なVuexアプリケーションを作成します。

// store/index.js
import { createStore } from 'vuex'
import axios from 'axios'
export default createStore({
    state: {
        users: []
    },
    getters: {
      getUsers: (state) => state.users
    },
    actions: {
      async fetchUsers({ commit }) {
          try {
            const data = await axios.get('https://jsonplaceholder.typicode.com/users')
              commit('SET_USERS', data.data)
            }
            catch (error) {
                alert(error)
                console.log(error)
            }
        }
    },
    mutations: {
        SET_USERS(state, users) {
          state.users = users
      }
    }
})

エンドポイントからデータをフェッチするためにasync/await形式を使用し、HTTPリクエストを行うためにAxiosを使用しています。

オブジェクト内のAPIフォームにリクエストを送信しactionsます。次に、tryブロック内で、dataHTTPリクエストに変数を割り当てます。応答が返されると、ミューテーションがコミットされ、アプリケーションの状態が更新されます。

catchエラーを警告したり、ブロック内のコンソールに記録したりすることもできます。

HelloWorld.vueファイルに次のコードを貼り付けます。

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h1>Made By Getters</h1>
  <div v-for='gettersUser in gettersUsers' :key='gettersUser.id'>
    {{gettersUser.id}} {{gettersUser.name}} {{gettersUser.address}}
    </div>
    <h1>Made By Actions</h1>
  <div v-for='user in users' :key='user.id'>
    {{user.id}} {{user.name}} {{user.address}}
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, computed } from 'vue';
//import the global store object from Vuex
import {useStore} from 'vuex'
// declare the store variable
const store = useStore();

const msg = ref("Welcome to my Vuex Store");

const getUsers = computed(() => {
  return store.getters.getUsers
})

const users = computed(() => {
  return store.state.users
})

onMounted(() => {
// dispatch the fetchUsers action which commits a mutation to update the state
  store.dispatch("fetchUsers");
})
</script>

localhost:8080ブラウザに戻って、行った変更を確認してください。

PiniaとAxiosでAPIを使用する

PiniaとAxiosを使用して、Vuexの例の出力を複製します。

//stores/users.js

import { defineStore } from 'pinia'
// Import axios to make HTTP requests
import axios from "axios"
export const useUserStore = defineStore("user", {
    state: () => ({
        users: [],
    }),
    getters: {
      getUsers(state){
          return state.users
        }
    },
    actions: {
      async fetchUsers() {
        try {
          const data = await axios.get('https://jsonplaceholder.typicode.com/users')
            this.users = data.data
          }
          catch (error) {
            alert(error)
            console.log(error)
        }
      }
    },
})

HelloWorld.vueファイル内のコードを次のように置き換えます。

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h1>Made By Getters</h1>
  <div v-for='gettersUser in getUsers' :key='gettersUser.id'>
    {{gettersUser.id}} {{gettersUser.name}} {{gettersUser.address}}
    </div>
    <h1>Made By Actions</h1>
  <div v-for='user in users' :key='user.id'>
    {{user.id}} {{user.name}} {{user.address}}
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
//import users store
import { useUserStore } from "../stores/users";
// declare store variable
const store = useUserStore();

const msg = ref("Welcome to my Vuex Store");

const getUsers = computed(() => {
  return store.getUsers
})
const users = computed(() => {
  return store.users
})

onMounted(() => {
  store.fetchUsers();
})
</script>

ピニアでは、ストアはデフォルトでモジュール式です。作成されたストアごとに、使用するコンポーネントにストアをインポートする必要があります。

これで、コンポーネント全体から簡単にアクセスできるように、をインポートして変数にuseUserStore割り当てます。store

Vuexのメソッドの代わりに、store.dispatch("fetchUsers")Piniaでは、アクションは関数と見なされ、メソッドstoreを使用して宣言された変数からアクセスできますstore.fetchUsers()

さまざまなVuexストア構造

以下は、最も単純なVuexストア構造であり、アクション、ゲッター、状態、およびミューテーションが呼び出され、でエクスポートされますindex.js file

注意:Piniaはモジュール式であるため、これらのVuexの例は当てはまらない場合があります。

├── index.html
└── src
    ├── components
    ├── App.vue
    └──store
       └── index.js         # where we assemble modules and export the store

アプリケーションが大きくなるにつれて、アクション、ミューテーション、ゲッター、および状態モジュールを独自の異なるファイルに分離する必要がある場合があります。

├── index.html
└── src
    ├── components
    ├── App.vue
    └──store
       ├── index.js        # where we assemble modules and export the
       ├── actions.js      # root actions
       ├── mutations.js    # root mutation
       ├── getters.js      # root getters
       └── state

単一の状態ツリーを使用しているため、アプリケーションのすべての状態は1つの大きなオブジェクト内に含まれています。これは、アクション、ミューテーション、および状態が大きくなるにつれてアプリケーションが大きくなり、ストアがさらに大きくなる可能性があり、それに追いつくことができない可能性があるため、理想的ではありません。

優れたソリューションは、ストアをモジュールにグループ化することです。各モジュールには、独自の状態、ミューテーション、アクション、およびゲッターを含めることができます。また、ネストされたモジュールを含めることもできるため、スケーラビリティーのオプションが増えます。

├── index.html
├── main.js
├── api
│   └── ... # abstractions for making API requests
├── components
│   ├── App.vue
│   └── ...
└── store
    ├── index.js          # where we assemble modules and export the store
    ├── actions.js        # root actions
    ├── mutations.js      # root mutations
    └── modules
        ├── cart.js       # cart module
        └── products.js

結論

このチュートリアルでは、状態管理とは何か、およびVueアプリケーションの状態を処理するためにVuex/Piniaなどのライブラリが必要な理由について説明しました。

さらに、Vuex / PiniaをデモンストレーションするためのシンプルなVueアプリケーションを作成し、さまざまなストア構造を学習して、アプリケーションに最適なものを決定できるようにしました。 

ソース:https ://blog.logrocket.com/consume-apis-with-vuex-pinia-axios/

#vuex  #pinia  #axios 

Welcome to Morioh!

Let's write, share knowledge and earn GEEK.