PiniaとVuex比較してみた

18703 ワード

背景

今まで、Vueの中に状態管理と言いましたら、Vuexでしょうになるけど、
Vue3が出て、Vue3の強力なcomposition apiの影響があって、
VueのエンジニアたちはVuexをリファクタリングして、素敵な状態管理ツールPinia生まれました。
VuexのRedux思考と比べ、Piniaはすごく軽くて、わかりやすいものになっています。
今はすでにVue家族の一員になり、Vue3を使う上に、オフィシャル的にお薦められています。

手順

手順はそんなに変わったものでもないと思います。
個人的には、piniaのapiは神レベルで、本当に簡単で、使いやすいかと思います。
詳細はpiniaのドキュメントで各apiを確認してください。

Vuex

VuexやっぱりRedux思考あるですが、こちらの手順は一番少なめなものかと思います。

  1. ライブラリーをインストールする
npm install vuex@next --save
# or with yarn
yarn add vuex@next --save
  1. storeを作る。普通にはsrcの下にstoreのフォルダを作って管理します。
src/store/vuex.ts
import {createStore} from 'vuex'
const useStore = createStore({
  state() {
    return { 
         name: '原神',
         version: '2.6',
	 gacha: 0,
      }
  },
  mutations: {
    addOne(state) {
      state.gacha++
    },
    addTen(state) {
      state.gacha = +10
    }
  }
})
  1. プロジェクトに状態管理かける
main.ts
import { createApp } from 'vue'
import App from './App.vue'
import {useStore} from './store'
createApp(App).use(store).mount('#app')

4.アクセス

src/view/index.vue
<template>
  <h3>{{name}}</h3>
  <h3>{{version}}</h3>
  <h3>{{gacha}}</h3>
  <button @click="GachaOne">単発</button>
  <button @click="GachaTen">10</button>
</template>
<script>
  import { computed } from 'vue'
  const store = useStore()
  export default defineComponent {
    name: 'Index',
    setup () {
      return {
        name: computed(() => store.name),
	version: computed(() => store.version),
	gacha: computed(() => store.gacha),
      }
    },
    GachaOne () {
      this.$store.commit('addOne')
    },
    GachaTen () {
      this.$store.commit('addTen')
    }
  }
</script>

Pinia

  1. ライブラリーをインストールする
yarn add pinia@next
# or with npm
npm install pinia@next
  1. プロジェクトに状態管理かける
main.ts
import { createApp } from "vue";
import { createPinia } from "pinia";
import App from "./App.vue";

createApp(App).use(createPinia()).mount("#app");
  1. storeを作る。普通にはsrcの下にstoreのフォルダを作って管理します。
src/store/pinia.ts
import { defineStore } from 'pinia'

export const gameStore = defineStore({
// id は必須+唯一です、管理しやすいためです
  id: 'game',
  state: () => ({
    name: '原神',
    version: '2.6',
    gacha: 0,
  }),
  getters: {
     //filterとか
  },
  actions: {
       //値をsetするとか
       ...
  }
})

4.アクセス

src/view/index.vue
<template>
  <h3>{{game.name}}</h3>
  <h3>{{game.version}}</h3>
  <h3>{{game.gacha}}</h3>
  <button @click="pinia.gacha++">単発</button>
  <button @click="pinia.gacha=+10">10</button>
</template>
<script setup>
  import { gameStore } from '../../store/pinia'
  const game = gameStore()
</script>

まとめ

Pinia Vuex
簡単 やや複雑
mutationなし、APIで($patch) mutationでデータ扱う
action縛りなし action色々制限
CompositionApiと相性いい(TS) CompositionApiと相性そんなに高くない(TS)
インジェクト要らない、APIで インジェクト必須
プロジェクト小さいな、中型レベル プロジェクト大きいレベル

色々な情報をまとめる、PiniaはなんだかVuex5に統合するではないと推測していますので、今後Piniaを押しても大丈夫かと思います。