I ran into a problem earlier where mapState() does not create (simple value retrieving) getters automatically for store modules. Or maybe it was a timing issue. The docs say this:
"When a component needs to make use of multiple store state properties or getters, declaring all these computed properties can get repetitive and verbose. To deal with this we can make use of the mapState helper which generates computed getter functions for us, saving us some keystrokes:"
Using mapState() in a component computed property worked great - until I moved some of that state into a module, at which point it quit working. Adding a getter to pull the state property did work but I dislike the code duplication when retrieving simple, not computed, values. If it was due to timing, is there a store.ready(app.use(store)) function somewhere?
// store.js
import { createStore } from 'vuex';
import products from './products.js'
import cart from './cart.js'
const store = createStore({
modules:{
products,
cart
},
state() {
return {
isLoggedIn: false,
}
},
mutations: {
login(state) {
state.isLoggedIn = true;
},
logout(state) {
state.isLoggedIn = false;
},
},
})
export default store;
// products.js
export default {
state() {
return {
products: [
{
id: 'p1',
image:
'https://upload.wikimedia.org/wikipedia/commons/thumb/5/5a/Books_HD_%288314929977%29.jpg/640px-Books_HD_%288314929977%29.jpg',
title: 'Book Collection',
description:
'A collection of must-read books. All-time classics included!',
price: 99.99,
},
],
}
},
getters:{
products(state){
return state.products;
}
}
}
<!-- productList.vue -->
<template>
<section>
<ul>
<product-item
v-for="prod in products"
:key="prod.id"
:id="prod.id"
:title="prod.title"
:image="prod.image"
:description="prod.description"
:price="prod.price"
></product-item>
</ul>
</section>
</template>
<script>
import ProductItem from '../components/products/ProductItem.vue';
import { mapState } from 'vuex'
//import { mapGetters } from 'vuex'
export default {
components: {
ProductItem,
},
computed: {
...mapState([ //This does not work
'products'
])
// ...mapGetters([ This does
// 'products'
// ])
},
mounted(){
console.log(this.products)
}
};
</script>
<style scoped>
ul {
list-style: none;
margin: 2rem auto;
padding: 0;
max-width: 40rem;
}
</style>
Module state is always namespaced. For example, your products
state in the products
module is only available under
// 👇 module 👇 state
store.state.products.products
To use mapState
with a module, you can use either of these options
computed: {
...mapState({
products: state => state.products.products
}),
...mapState("products", {
products: state.products
})
...mapState("products", [
"products"
])
}
Each of these will map the products
state from the products
module to this.products
in your component.
Your getters work because your modules are not namespaced and therefore...
By default, actions, mutations and getters inside modules are still registered under the global namespace