Reputation: 87
I'm developing a small project and i want to be able to use namespaces to avoid getters, mutations, actions, with same names.
As described in docs, the modules must be imported to store, and maps must receive the path to the right module.
I can import everything by omitting the path, but it throws duplicate getter key, if i specify the path it throws module namespace not found in mapActions():
this errors happen in both getters and actions.
This is my store modules:
Stock.js
const state = {
stocks: [
{id: 1, name: 'BMW', price: 110},
{id: 2, name: 'Google', price: 200},
{id: 3, name: 'Apple', price: 250},
{id: 4, name: 'Twitter', price: 8}
]
};
const getters = {
getStocks: state => state.stocks
};
const mutations = {
setStocks: (state, data) => state.stocks = data
};
const actions = {
SETSTOCKS: (store, data) => {
store.commit('setStocks', data)
}
};
export default {
namespace: true,
state,
getters,
mutations,
actions
};
StocksCopy.js
const state = {
stocks: [
{id: 1, name: 'Fiat', price: 110},
{id: 2, name: 'Bing', price: 200},
{id: 3, name: 'Microsoft', price: 250},
{id: 4, name: 'Facebook', price: 8}
]
};
const getters = {
getStocks: state => state.stocks
};
const mutations = {
setStocks: (state, data) => state.stocks = data
};
const actions = {
SETSTOCKS: (store, data) => {
store.commit('setStocks', data)
}
};
export default {
namespace: true,
state,
getters,
mutations,
actions
}
store.js
import Vue from 'vue'
import Vuex from 'vuex'
import stocks from './modules/stocks'
import stocksCopy from './modules/stocksCopy'
Vue.use(Vuex);
const debug = process.env.NODE_ENV !== 'production'
export default new Vuex.Store({
namespace: true,
state: {
},
getters: {
},
mutations: {
},
actions: {
},
modules: {
stocks,
stocksCopy,
},
strict: true,
});
Stocks.vue
<template>
<div class="container">
<div class="row">
<button class="btn btn-primary" @click="setStocks({name: 'test', price: 100})">set stocks</button>
<button class="btn btn-primary" @click="setStocksCopy({name: 'test', price: 100})">set stocksCopy</button>
</div>
<div class="row">
<pre>Stocks: {{stocksList}}</pre>
</div>
<div class="row">
<pre>StocksCopy: {{stocks}}</pre>
</div>
<div class="row">
<app-stocks-stock v-for="(stock) in stocksList" :stock="stock"></app-stocks-stock>
</div>
</div>
</template>
<script>
import { mapGetters, mapActions} from 'vuex'
import Stock from './Stock.vue'
export default {
name: "Stocks",
components: {
'app-stocks-stock': Stock
},
computed: {
...mapGetters({
stocksList: 'getStocks',
stocks: 'stocks'
})
},
data() {
return {
}
},
methods: {
...mapActions('stocksCopy', {
setStocksCopy: 'SETSTOCKS'
}),
...mapActions('stocks', {
setStocks: 'SETSTOCKS'
}),
}
}
</script>
<style scoped>
</style>
Errors:
[vuex] duplicate getter key: getStocks
[vuex] module namespace not found in mapActions(): stocksCopy/
Upvotes: 6
Views: 13756
Reputation: 51
i think you forget to import your store in index file, so in your project go to store folder and then go to index file and import your module
import example from "./module-example"
and add example to modules
export default function (/* { ssrContext } */) {
const Store = new Vuex.Store({
modules: {
// example
},
where "example" is the name of your store, and the path of index file is
src/store/index.js
Upvotes: 0
Reputation: 497
To use namespace, the right key is namespaced: true
instead namespace: true
After you correct it, you can use paths like 'moduleName/getterName' or 'moduleName/actionName' in the functions mapGetters()
or mapActions()
var { mapGetters, mapActions} = Vuex
const stock = {
namespaced: true, // namespaced instead namespace
state: {
stocks: [
{id: 1, name: 'BMW', price: 110},
{id: 2, name: 'Google', price: 200},
{id: 3, name: 'Apple', price: 250},
{id: 4, name: 'Twitter', price: 8}
]
},
getters: {
getStocks: state => state.stocks
},
mutations: {
setStocks: (state, data) => state.stocks = data
},
actions: {
SETSTOCKS: (store, data) => {
console.log('SETSTOCK in stock')
store.commit('setStocks', data)
}
}
}
const stockCopy = {
namespaced: true, // namespaced instead namespace
state: {
stocks: [
{id: 1, name: 'Fiat', price: 110},
{id: 2, name: 'Bing', price: 200},
{id: 3, name: 'Microsoft', price: 250},
{id: 4, name: 'Facebook', price: 8}
]
},
getters: {
getStocks: state => state.stocks
},
mutations: {
setStocks: (state, data) => state.stocks = data
},
actions: {
SETSTOCKS: (store, data) => {
console.log('SETSTOCK in stockCopy')
store.commit('setStocks', data)
}
}
}
const store = new Vuex.Store({
modules: {
stock,
stockCopy
},
strict: true,
})
window.main = new Vue({
el:'#vue',
store,
computed: {
...mapGetters({
stocksList1: 'stock/getStocks', // moduleName/getterName
stocksList2: 'stockCopy/getStocks' // moduleName/getterName
})
},
methods: {
...mapActions({
setStocksCopy: 'stockCopy/SETSTOCKS', // moduleName/actionName
setStocks: 'stock/SETSTOCKS' // moduleName/actionName
}),
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.min.js"></script>
<div id="vue">
<button @click="setStocks({foo: 'bar'})">reset</button>
{{ stocksList1 }}
<hr>
<button @click="setStocksCopy({bar:'foo'})">reset</button>
{{ stocksList2 }}
</div>
Upvotes: 13