【フロントエンド入門14】Vuexによる状態管理|大規模アプリでのデータ管理術

Vue.jsで小規模なアプリケーションを作る場合、各コンポーネントでデータを個別に管理することが可能です。しかし、大規模なアプリになると、コンポーネント間のデータ共有や状態管理が複雑になります。そこで役立つのがVuexです。本記事では、Vuexの基本概念、セットアップ方法、そして状態管理の実践について初心者向けにわかりやすく解説します。

Vuexとは?

Vuexの概要

Vuexは、Vue.js公式の状態管理ライブラリであり、アプリケーションの全体的な状態を一元管理します。コンポーネント間でデータを効率的に共有し、予測可能な方法で状態を操作することができます。

なぜVuexが必要なのか?

  • 小規模なアプリ:通常は親コンポーネントから子コンポーネントにpropsを渡したり、イベントを使ってデータをやり取りすれば十分です。
  • 大規模なアプリ:多くのコンポーネント間で頻繁にデータをやり取りする場合、propsやイベントだけでは管理が複雑になりやすいです。

Vuexを導入することで、アプリのすべての状態を一元化し、データの流れを整理できます。

Vuexの基本構成

Vuexは次の4つの主要な要素で構成されています:

1. State(状態)

アプリケーションで共有するデータを格納する場所です。

2. Mutations(ミューテーション)

状態を変更する唯一の方法であり、同期的に動作します。

3. Actions(アクション)

非同期処理を含む操作を行い、その後ミューテーションを呼び出します。

4. Getters(ゲッター)

ステートから計算された値を取得するために使用します。

Vuexのセットアップ方法

1. Vuexのインストール

Vuexはnpmを使ってインストールできます。

npm install vuex@next --save

2. ストアの作成

src/store/index.jsにストアを作成します。

import { createStore } from 'vuex';

const store = createStore({
  state() {
    return {
      count: 0
    };
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    incrementAsync({ commit }) {
      setTimeout(() => {
        commit('increment');
      }, 1000);
    }
  },
  getters: {
    doubleCount(state) {
      return state.count * 2;
    }
  }
});

export default store;

3. ストアの登録

ストアをVueアプリに登録します。

src/main.js

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

createApp(App)
  .use(store)
  .mount('#app');

Vuexの基本的な使い方

1. Stateの使用

コンポーネント内でステートを取得するには、mapStateヘルパーを使うか、this.$store.stateを直接参照します。

例:カウンターの表示

<template>
  <div>
    <p>カウント: {{ count }}</p>
    <button @click="increment">カウントを増やす</button>
  </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  computed: mapState(['count']),
  methods: {
    increment() {
      this.$store.commit('increment');
    }
  }
};
</script>

この例では、state.countの値を表示し、ボタンをクリックするたびにカウントが増加します。

2. Mutationsの使い方

ミューテーションは状態を変更するための唯一の方法です。ミューテーションを呼び出すには、commitメソッドを使用します。

ミューテーションの基本例

mutations: {
  increment(state) {
    state.count++;
  },
  setCount(state, payload) {
    state.count = payload;
  }
}
  • increment:カウントを1増やします。
  • setCount:渡された値でカウントを設定します。

3. Actionsの使い方

アクションは、非同期処理を実行し、その後ミューテーションを呼び出す役割を果たします。

アクションの例

actions: {
  asyncIncrement({ commit }) {
    setTimeout(() => {
      commit('increment');
    }, 1000);
  }
}

コンポーネントからアクションを呼び出すには、dispatchメソッドを使います。

<button @click="incrementAsync">1秒後にカウントを増やす</button>
methods: {
  incrementAsync() {
    this.$store.dispatch('asyncIncrement');
  }
}

4. Gettersの使い方

ゲッターはステートから計算された値を取得するために使用します。

ゲッターの定義

getters: {
  doubleCount(state) {
    return state.count * 2;
  }
}

コンポーネントでゲッターを使うには、mapGettersヘルパーを使います。

<p>ダブルカウント: {{ doubleCount }}</p>
computed: {
  ...mapGetters(['doubleCount'])
}

実践:Todoアプリの作成

Vuexを使ったシンプルなTodoアプリを作ってみましょう。

ストアの設定

const store = createStore({
  state() {
    return {
      todos: []
    };
  },
  mutations: {
    addTodo(state, todo) {
      state.todos.push(todo);
    },
    removeTodo(state, index) {
      state.todos.splice(index, 1);
    }
  },
  actions: {
    addTodoAsync({ commit }, todo) {
      setTimeout(() => {
        commit('addTodo', todo);
      }, 500);
    }
  }
});

コンポーネントの実装

<template>
  <div>
    <h2>Todoリスト</h2>
    <input v-model="newTodo" placeholder="新しいタスクを追加">
    <button @click="addTodo">追加</button>
    <ul>
      <li v-for="(todo, index) in todos" :key="index">
        {{ todo }} <button @click="removeTodo(index)">削除</button>
      </li>
    </ul>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex';

export default {
  data() {
    return {
      newTodo: ''
    };
  },
  computed: {
    ...mapState(['todos'])
  },
  methods: {
    ...mapMutations(['addTodo', 'removeTodo']),
    addTodo() {
      if (this.newTodo.trim()) {
        this.addTodo(this.newTodo);
        this.newTodo = '';
      }
    }
  }
};
</script>

このアプリでは、新しいタスクを追加し、リストに表示することができます。削除ボタンを押すとタスクがリストから消えます。

結論

Vuexを使えば、大規模アプリでもデータの整合性を保ちながら効率的に状態を管理できます。本記事で紹介した基本的な使い方をマスターしたら、次はモジュール化や永続化ストレージとの連携を学び、さらに高度な状態管理に挑戦してみましょう。