tekitoumemo’s diary

思ったことを書くだけ。長文版Twitter

[NustJS]外部ファイルからstoreにアクセスする

NuxtJSではコンポーネントやplugins、middlewareなどなど、contextにアクセス出来ないことがある。つまりstoreにアクセス出来ない。

やり方はいろいろあるが、自分なりの落とし所を書く。

globalで使う(やばい)

.eslintrc.js

globals: {
    $store: true,
    ...
}

plugins/global_store.js

export default function({ store }) {
  global.$store = store
}

nuxt.config.js

plugins: [
    { src: '@/plugins/global_store.js', ssr: false },
]

これでこう使う

export default class Hoge {
    static hoge() {
        $store.dispatch('hogehoge');
    }
}

シャローコピーだしまぁ良いかなーと思ったけど、状態のように常に変わるようなものをグローバルに置くのはまぁヤバイ。コンポーネントではthis.$store$storeどっちも使えるのがシビれる(悪い意味で

onNuxtReadyで初期化

let store
if (process.client) {
  window.onNuxtReady(({$store}) => {
    store = $store
  })
}

export default class Hoge {
    static hoge() {
        store.dispatch('hogehoge');
    }
}

なんか絶対よくない気がするけど、ググってもonNuxtReadyがなんだかわからない。公式のドキュメントがあれば読みたい。却下。

constructorで初期化

export default class Hoge {
  constructor(store) {
    this._store = store
  }
  get $store() {
     return this._store
  }
}

無難。staticで使えないので却下。

シンプルにインスタンス作る

export default class Hoge {
    static get $store() {
        if (!this._store) {
            this._store = new Vuex.Store(...)
        }
        return this._store
    }
}

無難でシンプル、が結果的には最初の実装と同じようにインスタンスはグローバルに。インスタンスメソッドからはthis.constructor.$storeで使う。this.$storeインスタンスが変わるのでシュチュエーションによっては悪い例だけど、今回は特定のclass経由でのみstoreをいじるのでまぁおっけいかも?

pluginsでstoreを注入

plugins/hoge.js

import Vue from 'vue'
export default ({ store }) => {
    Hoge.$store = store
    // Vueインスタンスとして使いたければ
    // Vue.prototype.$hoge = Hoge
    // Vue.prototype.$hoge.$store = store
}
export default class Hoge {
    static hoge() {
        $store.dispatch('hogehoge');
    }
}

Nuxtの初期化フェーズでクリーンなcontextとして扱えるのでこの方法が一番しっくりくる。別インスタンス作ってしまうとchromeのvuedevtoolでstateが確認出来ないので困る。

[参考]
Accessing the store from an external file · Issue #2005 · nuxt/nuxt.js · GitHub