Help us understand the problem. What is going on with this article?

【Nuxt.js】VuexモジュールモードでStore以下のファイル群を整理する時のあれこれ

More than 1 year has passed since last update.

はじめに

Nuxt.jsのVuexモジュールモードで、store以下のファイルが増えてきて整理したくなりました。
いざディレクトリを切ってファイルを整理し始めると、stateやactionへのアクセス仕方で少し手間取ったので...

今回は、store配下でディレクトリを切った時、名前空間の違うvuexモジュールやVueコンポーネントからVuexのモジュールにアクセスする方法を備忘録的にまめておきます。

store内の構成

例として以下のようなディレクトリ構成下で説明して行きます。(コードの中身に意味はないでスルーしてください
ちなみにNuxt.jsではstore/index.jsがストアインスタンスを返さない時、モジュールモードになります。詳しくはこちら

store/
  ┣ shared/
    ┣ auth.js
  ┣ pages/
    ┣ mypage.js
pages/
  ┣ mypage/
    ┣ index.vue
store/models/auth.js
export const state = () => ({
 token: null
})

export const mutations = {
  setToken(state, token) {
    state.token = token
  }
}

export const actions = {
  setToken({ commit }, token) {
    commit('setToken', token)
  },
  deleteToken({ commit }) {
    commit('setToken', null)
  }
}
store/pages/mypage.js
export const state = () => ({
  name: ''
})

export const mutations = {
  setName(state, name) {
    state.name = name
  }
}

export const actions = {
  login({ dispatch }, name) {
    dispatch('setName', name)
    dispatch('shared/auth/setToken', 'dummy', { root: true })
  },
  logout({ dispatch }) {
    dispatch('setName', '')
    dispatch('shared/auth/deleteToken', null, { root: true })
  },
  setName({ commit }, name) {
    commit('setName', name)
  }
}
pages/mypage/index.vue
<template>
  <section>
    <p>{{ name }}</p>
    <p>{{ this.$store.state.pages.mypage.name }}</p>
    <p @click="login('Alis')">login</p>
    <p @click="logout">logout</p>
  </section>
</template>

<script>
import { mapState, mapActions } from 'vuex'

export default {
  computed: {
    ...mapState('pages/mypage', ['name'])
  },
  methods: {
    ...mapActions('pages/mypage/', [
       'login',
       'logout'
    ])
  }
}
</script>

では細かく見ていきましょう。

名前空間の違うVuexモジュールにアクセスする

今回の例で言うとstore/pages/mypage.jsからstore/models/auth.jsを参照したい時は以下のような形でauthモジュールのアクションを呼び出せます。

dispatch('shared/auth/setToken', 'dummy', { root: true })
dispatch('shared/auth/deleteToken', null, { root: true })

ここで2つのミソがあります。

1つ目はモジュール内は相対パス扱いなので{ root => true }第3引数のオプションに渡さないとpages/mypage/shared/auth/...を参照しに行ってエラーになります。

2つ目はshared/auth/deleteTokenのように引数を受け取らないactionを呼ぶ場合は第2引数をnull埋めしないと{ root => true }が効かずactionが呼ばれません。
これはエラーにならないので意外と気づかないです...

ComponentからVuexモジュールにアクセスする

stateの参照

stateにアクセスする時は直接参照するか、バインディングヘルパーを使う方法があります。

直接参照は$storeオブジェクトを掘っていくことで参照できます。

this.$store.state.pages.mypage.name

バインディングヘルパーを使う場合は...mapStateを使い、storeからの相対パスでnamespaceを指定します。

<template>
 <p>{{ name }}</p>
</template>

<script>
import { mapState } from 'vuex'

export default {
  computed: {
    ...mapState('pages/mypage', ['name'])
  }
}

ちなみにayncdata()からはcontextにstoreオブジェクトがあるのでそれを使って参照出来ます。

asyncData({ store }) {
  store.state.shared.auth.token
}

アクションの参照

アクションもバイディングヘルパーを使えばstateと同じように参照できます。
ちなみにバインディングヘルパーは以下のような感じで複数のvuexモジュールを指定する事も出来ます。

<template>
  <div>
   <p @click="login('Alis')">login</p>
   <p @click="deleteToken">logout</p>
 </div>
</template>

<script>
import { mapActions } from 'vuex'

export default {
  methods: {
    ...mapActions('pages/mypage', [
       'login'
    ])
    ...mapActions('shared/auth', [
       'deleteToken'
    ])
  }

バリンティングヘルパーを使わない場合は以下の通りです。

export default {
  methods: {
    logout() {
       this.$store.dispatch('pages/mypage/logout')
     }
  }
}

まとめ

これでstore以下をディレクトリ切って整理出来ました。

yoshinbo
サービスエンジニアです。新規事業をよく担当します。
skill
株式会社SKILLはブロックチェーン関連サービス開発会社です。ブロックチェーン技術の社会実装を目指し、プロダクト開発および実証実験を行っています。
https://skill.luxe/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした