この記事は、ラクスパートナーズ AdventCalendar 2025の24日目の記事です。
(個人で25日連続投稿にチャレンジ中のカレンダーになります)
前回は、フロントエンドでよく聞く「状態(state)」という用語について解説をしました。
今回は、そんな状態の管理を行うライブラリのPiniaの特徴や使い方についてまとめたいと思います。
Pinia(ピー二ャ)とは?
Piniaは、状態の管理を行うVue.js用のライブラリです。
複数のページ、コンポーネント間で状態(state)を共有し、管理することができます。
特徴
以下ような特徴があります。
超軽量
なんと、Piniaは約1.5KBしかありません。
公式ドキュメントでも
「Extremely light(超軽量)。そこにあることすら忘れてしまうでしょう!」
と書かれていました。
Vuexよりも記述量が少ない
Vuexによる状態管理は、以下4つの要素で成り立っています。
- state:アプリケーション全体の「状態」を保存する
- mutations:stateに保存されている「状態」の値を更新する
- actions:mutaionsを呼び出す
- getters:stateに保存された「状態」の値を用いて、算出した結果を返す
一方、Piniaは以下で構成されています(各要素の役割はVuexと同じです)。
- state
- actions
- getters
actionsから直接stateを更新できるようになったことにより、mutaionsが丸ごとなくなりました。そのため、Vuexよりもシンプルに書くことができます(コードについては後ほど触れます)。
Hot module replacement
画面をリロードしなくても状態を更新することができるので、開発中の手間を減らすことができます。
サーバーサイドレンダリング(SSR)のサポート
PiniaはNuxt3、4にも対応しており、SSRを安全に実装することができます。シリアル化やXSS攻撃を気にする必要がありません。
TypeScriptのサポート
state/getters/actionsのいずれも型安全であり、型定義が自動で推論されます。
Vue3(Composition API)に対応
Composition APIにも対応しており、状態管理を少ない記述量で柔軟に書くことができます。
Vue Devtoolsに対応
Vue Devtoolsにも対応しており、「Piniaのストアの値が今どうなっているか」などを視覚的に確認しながら開発を進めることができます。
基本的な使い方
1. インストール
npm install piniaでPiniaをプロジェクトにインストールします。
Vue.jsのバージョンが2.7未満の場合は、Composition API(@vue/composition-api)もインストールしている必要があります。
Vue CLIを使用しているプロジェクトにPiniaを導入する場合は、非公式ですがこちらのライブラリをインストールする必要があるそうです。
https://github.com/wobsoriano/vue-cli-plugin-pinia
2. Piniaの設定を追加
main.tsに以下を記載します。
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')
3.srcにstoresを作成する
src内にstoresディレクトリを作成し、ここにPinia関連のコードを入れていきます。
今回は例として、counter.tsというファイルを作ってみます。
src
┗ stores
┗ counter.ts
4. ストアを定義する
作成したtsファイルで、defineStoreという関数を使用してストアを定義します。
defineStore('一意なストアの名前', オプション)といった形式で使用します。
import { defineStore } from 'pinia'
export const useCountStore = defineStore('count', {
// other options...
})
第一引数に一意な名前をつけておくのは、Piniaがストアをdevtools(Vue Devtoolsのことと思われます)へ接続する際に必要なためです。
また、慣習として、変数名は「use〇〇Store」のキャメルケースの形式で命名します。
5. state/getters/actionsを記載する
defineStoreの第二引数にstate/getters/actionsを書いていきます。
また、コンポーネントからストアに参照できるよう、忘れずexportしておきます。
import { defineStore } from 'pinia'
export const useCountStore = defineStore('count', {
state: () => ({
count: 0,
}),
getters: {
doubleCount: (state) => state.count * 2,
},
actions: {
increment() {
this.count++
},
randomize() {
this.count = Math.floor(Math.random() * 100)
}
}
})
6. コンポーネントからアクセスする
コンポーネントから以下のようにstate/getters/actionsを参照することができます。
<script setup>
import { useCountStore } from '../stores/count'
const counter = useCountStore()
</script>
<template>
<div>
<button type="button" @click="counter.increment()">
Count is {{ counter.count }}
</button>
<button type="buttton" @click="counter.randomize()">
Random
</button>
<p>Double Count is {{ counter.doubleCount }}</p>
</div>
</template>
useCountStoreをimportし、変数に格納したら、
変数.state
変数.getters
変数.actions
といった形式で参照することができます。
Piniaを使って簡単な数値のカウント機能を作成することができました。
基本的な使い方は以上となります。
Vuexとの関係性
もともと、Vue.jsでは主にVuexという状態管理ライブラリがエコシステムとして使われていました。
2021年にはVuexのバージョン4.0がリリースされ、Vue3やTypeScriptにも対応されるなど、Vuexは長らく使われてきました。
しかし、その後Vue3から標準の状態管理ライブラリとして推奨されるようになったのがPiniaです。
以下はVuexのドキュメントから引用した文章です。
Pinia is now the new default
The official state management library for Vue has changed to Pinia. Pinia has almost the exact same or enhanced API as Vuex 5, described in Vuex 5 RFC. You could simply consider Pinia as Vuex 5 with a different name. Pinia also works with Vue 2.x as well.
Vuex 3 and 4 will still be maintained. However, it's unlikely to add new functionalities to it. Vuex and Pinia can be installed in the same project. If you're migrating existing Vuex app to Pinia, it might be a suitable option. However, if you're planning to start a new project, we highly recommend using Pinia instead.
要約しますと、
- PiniaはVuex5とほぼ同じ、または強化されたAPIを備えている
- VuexとPiniaは互換性があり、同じプロジェクトで併用できる(新規プロジェクトではPiniaのみの使用推奨)
と書かれています。
つまり、PiniaはVuexの後継のような存在であることが伺えます。
Piniaは、Vue2.xへのサポートを2025年に廃止しています(Composition APIでなくとも動作するようなので、Options APIは引き続き使えそうです)
Since then, the initial principles have remained the same and Vue 2 support has been dropped in 2025, but Pinia doesn't require you to use the composition API.
以上となります。
やはりVuexのmutationsがなくなるとかなりすっきりしますね。直感的に理解しやすくなったので、学習コストが低めな点も魅力的です。
今回はPiniaの基本的な内容の紹介なので、また細かい機能の部分は今後触れていきたいと思います。
ここまで読んでくださりありがとうございました。
参考
以下、参考にさせていただいた記事です。
ありがとうございました!