概要

Vue 3 の新しい状態管理ライブラリ Pinia の使い方について簡単に紹介します。

インストール

まずはcreatePiniaを呼び出します。
その前にuseUserStoreなどの個別のストアを呼び出してはいけません。

import { useUserStore } from '@/stores/user'
import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)
const pinia = createPinia()
app.use(pinia)

const store = useUserStore()

ストアの作成

Piniaを読み込んだら、ストアを作成します。

簡単なストアの例を以下に示します。
状態countとその値を更新させるincrementを定義しています。

defineStoreの第一引数にはストアの名前を渡します。
これはストア全体でユニークなものである必要があります。

export const useStore = defineStore('count', {
  state: () => ({ count: 0 }),
  actions: {
    increment(amount) { this.count = this.count + amount }
  }
}

ストアを使うにはコンポーネントのsetupで呼び出します。
値を分割代入して使いたい場合はstoreToRefsでストアをラップします。
ラップしないと値がリアクティブでなくなります。

import { useStore } from '@/stores/count'
import { storeToRefs } from 'pinia'

export default {
  setup() {
    const store = useStore()
    const { count } = storeToRefs(store)

    return { store }
  },
}

ステート

ストアの値は直接読みだすことができます。
そのまま書き換えることも可能です。

const store = useStore()
store.count = 100

ゲッター

ゲッターはdefineStoreの引数のgettersプロパティ内に定義します。
用途としてはコンポーネントのcomputedのような使い方をします。

export const useStore = defineStore('count', {
  state: () => ({ count: 0 }),
  getters: {
    doubleCount: (state) => state.count * 2,
  },
})

アクション

コンポーネントのmethodsに相当するのがアクションです。
defineStoreactionsプロパティに定義します。
アプリケーションのビジネスロジックを書く場所として最適です。

export const useStore = defineStore('count', {
  state: () => ({ count: 0 }),
  actions: {
    increment(amount) { this.count = this.count + amount }
  },
})

アクションの呼び出しはメソッドのように簡単にできます。

import { useStore } from '@/stores/count'
import { storeToRefs } from 'pinia'

export default {
  setup() {
    const store = useStore()
    store.increment(100)

    return { store }
  },
}