Nuxt3でVuexの代わりにuseStateで状態管理
Nuxt3 (Beta)では、Nuxt2で主要機能となっていたグローバルな状態管理ライブラリであるVuexがバンドルされておらず、代わりにuseStateを使うことで簡単に状態管理できるようになった。その背景として、グローバルな状態管理ストアにアプリが依存するリスクやテストとの相性が問題視されている。
useStateの定義
useState<T>(key: string, init?: () => T): Ref<T>
基本的な使い方
公式サイトで紹介されているように、コンポーネント内で利用する場合は、setup関数の中でuseStateでキーと初期値を定義すればよい。useStateの返却値はリアクティブなので、ボタンクリックで値を更新できて、処理で値を変更すればそれが画面表示にも反映される。
<template>
<div>
Counter: {{ counter }}
<button @click="counter++">
+
</button>
<button @click="counter--">
-
</button>
</div>
</template>
<script setup>
const counter = useState('counter', () => 0)
</script>
状態の共有
上の例ではコンポーネント内でしか状態を利用できないので、グローバルで状態を共有したい場合は、composablesディレクトリにuseStateを定義してコンポーネントでインポートして利用する。
// composables/useCounter.ts
import type { Ref } from 'vue'
export const useCounter = () => {
// stateの定義
const counter: Ref<number> = useState('counter', () => 0)
// stateの更新処理
const updateCounter = (counter: Ref<number>) => (value: number) => {
counter.value = value;
}
return {
counter: readonly(counter), // stateはreadonlyとし、update関数を通してのみ更新できる
updateCounter: updateCounter(counter),
}
}
<!-- xxx.vue -->
<template>
<div>
Counter: {{ counter }}
<button @click="updateCounter(counter + 1)">
+
</button>
<button @click="updateCounter(counter - 1)">
-
</button>
</div>
</template>
<script setup>
const { counter, updateCounter } = useCounter()
// <script setup>の場合はreturnなしでOK
</script>