catmal
catmal

Reputation: 1758

Vuex unable to use modules

I am using Vue with Webpacker with Rails. I am having some problem with Vuex, specifially on using modules.

application.js:

import store from '../store/store'
Vue.prototype.$store = store;


document.addEventListener('turbolinks:load', () => {
  axios.defaults.headers.common['X-CSRF-Token'] = document.querySelector('meta[name="csrf-token"]').getAttribute('content')
  const app = new Vue({
    el: '[data-behavior="vue"]',
    store
  })
})

store.js:

import Vue from 'vue/dist/vue.esm'
import Vuex from 'vuex';
import axios from 'axios';
import itemstore from'./modules/itemstore'
Vue.use(Vuex)

import VueAxios from 'vue-axios'

Vue.use(VueAxios, axios)

const store = new Vuex.Store({
............
  modules: {
    itemstore
  }

})


export default store;

itemstore.js:

import axios from 'axios';


const itemstore = {
  state: {
    items: [],
},
actions: {
    loadItems ({ commit }) {
        axios
        .get('/items.json')
        .then(r => r.data)
        .then(items => {
            commit('SET_ITEMS', items);
        })
    }
},
mutations: {
    SET_ITEMS (state, items) {
        state.items = items
    }
},
}

export default itemstore;

In my component:

    mounted () {
      this.$store.dispatch('loadItems')
    },
    computed: {
        ...mapState([
            'items'
        ]),
      }

First to get the main store imported I need Vue.prototype.$store = store;

Secondly once i move those states, actions and mutations from store.js to itemstore.js, items gets undefined. What am I doing wrong?

Upvotes: 0

Views: 199

Answers (1)

skirtle
skirtle

Reputation: 29132

The namespaced setting will cause the actions, mutations and setters of a store to be namespaced based on the module name. The state of a module, however, is always separated off into its own subtree within state, even if namespacing is not being used.

So this won't work:

...mapState([
   'items'
]),

This is looking for an items property in the root state.

Instead you can use something like:

...mapState({
    items: state => state.itemstore.items
})

You might be tempted to try to write it like this:

...mapState('itemstore', ['items'])

However, passing the module name as the first argument to mapState will only work with namespaced modules.

Upvotes: 1

Related Questions