PiniaでVue 3アプリを革新する状態管理ガイド

現代のフロントエンド開発において、状態管理はアプリケーションのパフォーマンスと保守性に直結する重要な要素です。Vue 3の導入に伴い、公式推奨の状態管理ライブラリであるPiniaが注目を集めています。本記事では、Piniaの導入から実装までを解説し、コードサンプルを通じて実践的な使い方を紹介します。

Piniaとは?

Piniaは、Vuexの代替として設計されたVue用状態管理ライブラリです。特徴的な点は以下の通り:

  • シンプルなAPI:defineStore関数を用いて簡単にストアを定義可能
  • Composition APIとの親和性:Vue 3のComposition APIと連携して、リアクティブな状態管理を実現
  • 開発体験の向上:デバッグツールによるホットリロードやタイムトラベル機能をサポート

導入と初期設定

npmまたはyarnでインストールします:

# npmの場合
npm install pinia

# yarnの場合
yarn add pinia

Vue 3プロジェクトに接続するには以下のように設定します:

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

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

app.use(pinia)
app.mount('#app')

ストアの作成と使用

Piniaの核心となるAPIはdefineStoreです。以下にカウンターアプリを例にしたストアの実装を示します。

ストアの定義

// stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    currentCount: 0
  }),
  getters: {
    doubleValue(state) {
      return state.currentCount * 2
    }
  },
  actions: {
    increment() {
      this.currentCount++
    },
    decrement() {
      this.currentCount--
    }
  }
})

コンポーネントでの使用

<!-- components/Counter.vue -->
<template>
  <div>
    <h2>カウンターアプリ</h2>
    <p>現在値: {{ counter.currentCount }}</p>
    <p>倍値: {{ counter.doubleValue }}</p>
    <button @click="counter.increment">増やす</button>
    <button @click="counter.decrement">減らす</button>
  </div>
</template>

<script setup>
import { useCounterStore } from '../stores/counter'

const counter = useCounterStore()
</script>

<style scoped>
button {
  margin-right: 8px;
}
</style>

高度な使い方

複数ストアの統合

大規模アプリでは、以下のように関連するストアを分離して管理できます:

// stores/user.js
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({
    username: '',
    isLoggedIn: false
  }),
  actions: {
    login(name) {
      this.username = name
      this.isLoggedIn = true
    },
    logout() {
      this.username = ''
      this.isLoggedIn = false
    }
  }
})

コンポーネント内で複数ストアを使用する例:

<!-- components/Dashboard.vue -->
<template>
  <div>
    <h2>ダッシュボード</h2>
    <div v-if="user.isLoggedIn">
      <p>ようこそ、{{ user.username }}さん!</p>
      <button @click="user.logout">ログアウト</button>
    </div>
    <div v-else>
      <button @click="user.login('田中')">ログイン</button>
    </div>
    <Counter />
  </div>
</template>

<script setup>
import Counter from './Counter.vue'
import { useUserStore } from '../stores/user'

const user = useUserStore()
</script>

状態の永続化

永続化プラグインを導入することで、localStorageに状態を保存できます:

npm install pinia-plugin-persistedstate

プラグインの設定:

// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import piniaPersist from 'pinia-plugin-persistedstate'
import App from './App.vue'

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

pinia.use(piniaPersist)

app.use(pinia)
app.mount('#app')

ストアの永続化設定:

// stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    currentCount: 0
  }),
  actions: {
    increment() {
      this.currentCount++
    }
  },
  persist: true
})

タグ: Pinia Vue3 状態管理 CompositionAPI pinia-plugin-persistedstate

6月29日 22:49 投稿