Vuex の新しいライバル? Pinia のご紹介
Pinia は Vue.js 向けの状態管理ライブラリです。
昨年に知ったときは「experimental なプロジェクト」という注意書きがあったのですが、先月にその表記がなくなっていたので少し触ってみました。
(ちなみにスペイン語でパイナップルの意味だそうです)
ストア定義
下記は GitHub の README から引用したコードで、一部コメントを翻訳してあります。
import { defineStore } from 'pinia'
export const useMainStore = defineStore({
// ストアの名前
id: 'main',
// 初期状態を返す関数
state: () => ({
counter: 0,
name: 'Eduardo',
}),
getters: {
doubleCount() {
return this.counter * 2
},
// ゲッターの中で他のゲッターを使う
doubleCountPlusOne() {
return this.doubleCount * 2 + 1
},
},
actions: {
reset() {
// `this` はストアのインスタンス
this.counter = 0
},
},
})
大まかには Vuex と似ていて、以下の 2 点が主な違いです。
- ストアの内容を this で取得すること
- mutations がなく action 内で state の値を直接変更できること
個人的に Vuex の mutations はボイラープレート感が強いと思っていたので、直接変更できるのは良いですね。
もちろん型の補完も効きます。
ストア呼び出し
こちらも README からの引用です。
import { useMainStore } from '@/stores/main'
export default defineComponent({
setup() {
const main = useMainStore()
return {
// ストア全体のアクセス
main,
// 特定の state へのアクセス
state: computed(() => main.counter),
// 特定のゲッターへのアクセス
doubleCount: computed(() => main.doubleCount),
}
},
})
呼び出し方もほぼ Vuex と同じです。
先程 export した use- 関数でストアを取得して、state や getters の値は computed でラップします。
Vuex だと store.state.counter
のようになりますが、Pinia はストアに直接プロパティがはえています。
(コードにはないですが)action も main.reset()
のようにメソッドとして呼び出せるので便利です。
まとめ
以前から typed-vuex というラッパーライブラリを使用していたので、よく言われる「Vuex は型が聞かなくてつらい」ということはなかったのですが、大量の mutations を書く必要があったりするとつらいです。
その点 Pinia はコードの量が少なくて使いやすいです。ただし、ストアの外でも値を直接書き換えることができてしまう(main.counter = 1
とか)ので、そこは欠点に感じるかも知れません(大規模な開発には向いてなさそう)。
今後イミュータブルにするオプションなどがつくといいのですが。
また、Vuex5 の RFC が先日発表されました。mutations がなくなるなど Pinia のように使いやすくなりそうなので、Vuex の動向にも注目していきたいと思います。
Discussion