🐓
公式リリースされた Vuex 4 を使ってVue Composition API で状態管理する
先日、Vue Composition APIに完全対応したVuexが公式に発表されました。この記事では、その導入方法や、Vue Composition APIでの使用法を中心にまとめていきたいと思います。
インストール
現在(2020/2/3)において、既存のリポジトリにVuexを導入するには、
# npm の場合
npm install vuex@next --save
# yarn の場合
yarn add vuex@next --save
で、インストールします。
続いて、/store/index.ts
で、
import { createStore } from 'vuex'
export const store = createStore({
state () {
return {
count: 0
}
},
mutations: {
increment (state) {
state.count++
}
}
})
とします。
main.ts
にて、
import { createApp } from 'vue'
import App from './App.vue'
import router from './router';
import {store} from "./store";
const app = createApp(App)
.use(store)
.use(router)
router.isReady().then(() => {
app.mount('#app');
});
これにより、 Vuexの初期設定は完了です。
Vue Composition API 上で Vuex を呼び出す。
Vue 3より公式に導入されたVue Composition APIでVuexを実際に使用していきます。setup()
内ではthis.$store
を使用できません。代わりに useStore()
を使用してcomponent内でGlobal Stateを扱います。
Vuexにおいて、
- store, getterを使うとき →
computed()
を利用する - mutation, actionを使うとき →
methods
を利用する
// 省略
<script>
import {computed} from "vue"
import {useStore} from "vuex"
export default {
setup(){
const store = useStore()
return {
// state を呼び出す場合
count: computed(()=>store.state.count),
// getters を呼び出す場合
double: coumputed(()=>store.getters.double),
// mutation を呼び出す場合
increment:() =>store.commit("increment"),
// action を呼び出す場合
asyncIncrement:() => store.dispatch("asyncIncrement")
}
}
}
</script>
以上のように、setup()
内でVuexを使用します。
TypeScript Support
Vue 3.xまでは、 Vuexの型を定義する上で、公式が GetterTree, ActionTree, MutationTree
などを提供しています。
しかし、
- Getterの戻り値の型が
any
になってしまう - ActionとMutationのpayloadが
any
になる - Editor自体のTypeScriptの型補完がうまくいかない
などの問題からTypeScriptとの相性がよくありませんでした。
Vue 4.0から、InjectionKey
を使用して型を定義します。
先ほどの /store/index.ts
に型を定義します。
import {InjectionKey} from "vue"
import { createStore, Store, useStore as baseUseStore } from 'vuex'
export interface GlobalState{
count:number
}
export const StateKey: InjectionKey<Store<GlobalState>> = Symbol()
export const store = createStore({
state () {
return {
count: 0
}
}
})
// useState を呼び出す度、 StateKey で型を定義するのを避けるために、ここであらかじめ定義する
export function useStore(){
return baseUseStore(StateKey)
}
以上で、useStore()
に型を付与したものをComponent内で使用できます。
Discussion