🦖

Vue.js(Piniaについて)

2023/05/31に公開

Piniaとは

vue3で使用が推奨されている状態管理ライブラリ

インストール方法

npm install pinia

使い方

PiniaをVueのappインスタンスで使用できるようにする

main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia' //インポート
import App from './App.vue'

const app = createApp(App)
app.use(createPinia()) //appインスタンスに適用
app.mount('#app')

Store

1. defineStore

storeを定義する関数で戻り値を設定して他のファイルで使用できるようにする
use~~Storeという名前で設定されることがほとんどで、私が参画してるプロジェクトもこの命名規則
第一引数:Storeのid、第二引数:Storeを定義するObject
もしくは第一引数にStoreを定義するObjectとしてその中にidを記載することも可(下の例もこちら)

2. state

管理する値とその初期値を定義する
下の例では、counterという値が初期値「0」で定義されている

3. getters

stateのデータを整形したい場合などはこちらに記載する
stateのデータにアクセスする場合は「state.counter」のようにstate.~~でアクセスできる
下の例ではdoubleCountという整形したあたいはcounter × 2の値を返すように設定される

4. actions

値を更新するメソッドを定義する
stateのデータにアクセスする場合は「this.counter」のようにthis.~~でアクセスできる
下の例ではincrement()関数が呼ばれたらcounter + 1となるように値を更新する
私が参画しているプロジェクトではこちらでアピからの返却値をstateに設定している。

counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore({ // ・・・1
  id: 'counter',
  state: () => ({ // ・・・2
    counter: 0
  }),
  getters: { // ・・・3
    doubleCount: (state) => state.counter * 2
  },
  actions: { // ・・・4
    increment() {
      this.counter++
    }
  }
})

Vueファイルで出力する方法

App.vue
<template>
  <div>
    <div>Counter: {{ counterStore.counter }}</div> // ・・・2のstateの値を表示
    <div>DoubleCount: {{ counterStore.doubleCount }}</div> // ・・・3のgettersの値を表示
    <button @click="counterStore.increment()">increment!</button> // ・・・4のactions後の値を表示
  </div>
</template>

<script setup>
// ・・・1のimportしてきたuseCounterStoreをcounterStoreとしてVueファイルで使用できるように定義
import { useCounterStore } from '../store/count.js';
const counterStore = useCounterStore();
</script>

storeToRefs

以下の記述だとStateを参照している値がリアクティブにならないためstoreToRefsを使うのが好ましい。以下の記載だとcounterStore.increment()が実行された際、counter、doubleCountが変化しない。

js
const { counter, doubleCount, increment } = useCounterStore();

storeToRefsを使う場合の記載

App.vue
<template>
  <div>
    <div>Counter: {{ counter }}</div>
    <div>DoubleCount: {{ doubleCount }}</div> 
    <button @click="counterStore.increment()">increment!</button> 
  </div>
</template>

<script setup>
// ・・・storeToRefsの引数にcounterStoreを設定しcount, doubleCountを定義するとリアクティブ性が壊れない
import { useCounterStore } from '../store/count.js';
import { storeToRefs } from 'pinia';

const counterStore = useCounterStore();
const { count, doubleCount } = storeToRefs(counterStore);
const { increment } = counterStore;
</script>

Stateのリセット

store.$reset()を使用して、Stateを定義した初期状態にリセットが可能。

App.vue
<template>
  <div>
    <div>Counter: {{ counter }}</div>
    <div>DoubleCount: {{ doubleCount }}</div> 
    <button @click="counterStore.increment()">increment!</button>
    <button @click="counterStore.$reset()">Reset!!</button>
  </div>
</template>

<script setup>
// ・・・storeToRefsの引数にcounterStoreを設定しcount, doubleCountを定義するとリアクティブ性が壊れない
import { useCounterStore } from '../store/count.js';
import { storeToRefs } from 'pinia';

const counterStore = useCounterStore();
const { count, doubleCount } = storeToRefs(counterStore);
const { increment } = counterStore;
</script>

Discussion