Nuxtでstore.commitを呼び出すラッパー関数を作る
NuxtのPageやComponentからStoreに値を更新する時、以下のようにstore.commitを呼びます。
this.$store.commit("analytics.incrementClickCount")
サーバーサイドでのみ実行されるasyncDataではContextを通じて呼びます。
// Nuxt公式のサンプルではcontextの部分がappになっていて混乱するのですが、
// 実体はContextです。
async asyncData(context) {
context.store.commit("analytics.incrementClickCount")
}
store/analytics.jsは以下のように実装されているとします。
[store/analytics.js]
export const state = () => ({
clickCount: 0
})
export const mutations = {
incrementClickCount(state) {
state.clickCount++
}
}
このincrementClickCountを頻繁に呼ぶことがある場合、毎回、
this.$store.commit("analytics.incrementClickCount")
と書くのはめんどくさいと思うかもしれません。
これを、
this.$incrementClickCount()
のように呼べると楽ですよね。Pluginを作ってそれを実現してみます。
[plugins/analytics.js]
export default ({ context }, inject) => {
inject("incrementClickCount", () => {
context.store.commit("analytics.incrementClickCount")
})
}
nuxt.config.jsでこのPluginを有効にします。
[nuxt.config.js]
plugins: [
{ src: '~/plugins/analytics.js' }
// serverのみならmodeをserverにする。clientのみならmodeをclientにする
{ src: "~/plugins/analytics.js", mode: "server" }
]
これで、PageやComponentでthis.$incrementClickCount()で呼び出せるようになります。
Pluginの実装をTypeScriptでしたい場合は以下のようにします。
[plugins/analytics.ts]
import { Plugin } from '@nuxt/types'
// PageやComponentでthis.$incrementClickCount()と書いた時、
// トランスパイルエラーにならないよう宣言
declare module 'vue/types/vue' {
interface Vue {
$incrementClickCount(): void
}
}
// asyncData(context)などでcontext.$incrementClickCount()と書いた時、
// トランスパイルエラーにならないよう宣言
declare module '@nuxt/types' {
interface Context {
$incrementClickCount(): void
}
}
const myPlugin: Plugin = (context, inject) => {
inject("incrementClickCount", () => {
context.store.commit("analytics/incrementClickCount")
})
}
export default myPlugin
こちらが参考になります。