🍋

vue3における状態管理ライブラリについておさらい

2024/07/12に公開

ライブラリについて

Vue3における状態管理ライブラリは、VuexとPiniaが存在する。
これらは、アプリケーションの状態を一元管理し、コンポーネント間での状態共有を容易にするために使用される。以下に、それぞれの特徴と使い方について詳しく説明する。

Vuex

Vuexは、Vue.jsアプリケーション用の公式状態管理ライブラリで、Fluxアーキテクチャに基づいている。Vue 2でも広く使用されており、Vue 3にも対応している。

基本構造

  1. State:アプリケーションの状態を保持するオブジェクト
  2. Getters:Stateの値を取得するための関数。
  3. Mutations:Stateを変更するための関数。動機的に動作する。
  4. Actions:Mutationsをコミットするための関数。非同期操作もこの関数で行う。
  5. Modules:大規模なアプリケー読んでStateを分割するための方法。

インストール・基本的な使い方

npm install vuex@next
import { createStore } from 'vuex';

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

export default store;

Vueアプリケーションを提供する

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

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

コンポーネント内での使用例

<template>
  <div>
    <p>{{ count }}</p>
    <p>{{ doubleCount }}</p>
    <button @click="increment">Increment</button>
    <button @click="incrementAsync">Increment Async</button>
  </div>
</template>

<script>
<template>
  <div>
    <p>{{ count }}</p>
    <p>{{ doubleCount }}</p>
    <button @click="increment">Increment</button>
    <button @click="incrementAsync">Increment Async</button>
  </div>
</template>

<script lang="ts">
import { defineComponent, computed } from 'vue';
import { useStore } from 'vuex';

export default defineComponent({
  setup() {
    const store = useStore();

    const count = computed(() => store.state.count);
    const doubleCount = computed(() => store.getters.doubleCount);

    const increment = () => {
      store.commit('increment');
    };

    const incrementAsync = () => {
      store.dispatch('incrementAsync');
    };

    return {
      count,
      doubleCount,
      increment,
      incrementAsync
    };
  }
});
</script>

Pinia

piniaは、Vue3向けの次世代状態管理ライブラリで、よりシンプルで直感的なAPIを提供する。アプリケーションの状態管理を一元化するが、使いやすさと柔軟性を重視している。

インストールとストアの設定

インストール

npm install pinia

ストアの設定

import { defineStore } from 'pinia';

// ストアの型定義
interface State {
  count: number;
}

export const useCounterStore = defineStore('counter', {
  state: (): State => ({
    count: 0
  }),
  getters: {
    doubleCount: (state) => state.count * 2
  },
  actions: {
    increment() {
      this.count++;
    },
    incrementAsync() {
      setTimeout(() => {
        this.increment();
      }, 1000);
    }
  }
});

vueアプリケーションへのストアの提供

import { createApp } from 'vue';
import App from './App.vue';
import { createPinia } from 'pinia';

const app = createApp(App);
const pinia = createPinia();
app.use(pinia);
app.mount('#app');

コンポーネント内での使用

<template>
  <div>
    <p>{{ count }}</p>
    <p>{{ doubleCount }}</p>
    <button @click="increment">Increment</button>
    <button @click="incrementAsync">Increment Async</button>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import { useCounterStore } from '@/stores/counter';

export default defineComponent({
  setup() {
    const store = useCounterStore();

    return {
      count: store.$state.count,
      doubleCount: store.doubleCount,
      increment: store.increment,
      incrementAsync: store.incrementAsync
    };
  }
});
</script>

比較

  1. APIのシンプルさ:Piniaの方がシンプルで、CompositionAPIに馴染みのある開発者にとって直感的。
  2. モジュール化:Vuexはモジュールの概念を提供するが、Piniaはストアごとに独立しているため、モジュールの必要性がない。
  3. Vue3対応:PiniaはVue3に設計されており、Vue3の機能を最大限に活用している。VuexはVue3に対応しているが、元々はVue2向けに設計されているため、やや古い設計が残っている。現在は、Piniaの利用での状態管理が主流となっている。

Discussion