Nuxt3をいろいろ試していたときの備忘録。
Vuexが含まれなくなり、ComposablesやuseStateの登場で、
大きく変わっている印象。
composablesディレクトリとは?
Composablesとは?
Vue3のドキュメントだとこのあたり。
・Composables | Vue.js
In the context of Vue applications, a "composable" is a function that leverages Vue Composition API to encapsulate and reuse stateful logic.
"composable"は、VueのComposition APIを活用したstatefulな関数
ぱっと分かりづらいけど、Reusability(再利用性)のカテゴリに入っていて、
状態をもつ関数が"composable"という感じ。
例では、マウスやlocalなどが紹介されている。
・Nuxt 3 - State Management
useStateとは?
- SSR-friendlyなコンポーネント間で共有できるステートのcomposable
- SSR-friendlyな
ref()
の代替え - その値は、サーバー側のレンダリング後(クライアント側のハイドレーション中)に保持され、
一意のキーを使用してすべてのコンポーネント間で共有される useState
は、setup()
内か、Lifecycle Hooksでしか利用できない
Nuxt3のドキュメントだとこのあたり。
・Nuxt 3 - State Management
・Nuxt 3 - useState
useStateを使った状態管理
vuexのようなStoreのように、保持する状態(state)と
状態を操作するActionみたいな感じにしている。
// ~/composables/counterStore.ts import { Ref } from "nuxt/dist/app/compat/capi"; type CounterState = { count: number; }; export const useCounterStore = () => { const state = useState<CounterState>("counter_state", () => ({ count: 0, })); return { state: readonly(state), countUp: countUp(state), setCount: setCount(state), }; }; const countUp = (state: Ref<CounterState>) => { return () => state.value.count++; }; const setCount = (state: Ref<CounterState>) => { return (count: number) => (state.value.count = count); };
auto-importしてくれるので、使うときはこんな感じ。
<script lang="ts" setup> const counterStore = useCounterStore(); const { state } = counterStore; </script> <template> <div> <div>{{ state.count }}</div> <button @click="counterStore.countUp">countUp</button> <button @click="counterStore.setCount(0)">reset</button> </div> </template>
TypeScriptのクラスで書いてもいけそうだった
import { Ref } from "nuxt/dist/app/compat/capi"; type CounterState = { count: number; }; export const useCounterStore = () => { return new CounterStore(); }; class CounterStore { _state: Ref<CounterState>; constructor() { this._state = useState<CounterState>("counter_state", () => ({ count: 0, })); } get state() { return readonly(this._state); } countUp() { this.setCount(this._state.value.count + 1); } setCount(count: number) { this._state.value.count = count; } }
"counter_state"
のように保持する状態のkey/idを指定するので、
全体で重複がないように気をつけないといけない。
以上!! 状態管理周りも理解できてきた気がする(*´ω`*)