I have developed an ecommerce application using Vue.js, and here is a snippet of the store configuration:
state: {
cart: [],
totalItems: {
count: 0
}
},
getters: {
totalItems(){
if(window.localStorage.totalItems){
return JSON.parse(window.localStorage.totalItems)
}
else{
let totalItems = { count: 0}
return totalItems
}
}
},
mutations: {
setCart(state, cart){
state.cart = cart
window.localStorage.cart = JSON.stringify(cart)
},
setTotalItems(state, totalItems){
state.totalItems = totalItems
window.localStorage.totalItems = JSON.stringify(totalItems)
}
},
actions: {
addToCart({ commit, getters }, productId){
let cart = getters.cart
let totalItems = getters.totalItems
if(cart.length == 0){
cart.push({id: productId, quantity: 1})
totalItems.count++
}
else if(cart.find(({ id }) => id == productId)){
let item = cart.find(({ id }) => id == productId)
item.quantity++
totalItems.count++
}
else{
cart.push({id: productId, quantity: 1})
totalItems.count++
}
commit('setCart', cart)
commit('setTotalItems', totalItems)
},
setTotalItems({ commit }, totalItems){
commit('setTotalItems', totalItems)
}
}
The App.vue file includes the following template:
<template>
<v-app>
<v-app-bar
app
color="red"
dark
>
<v-btn text to="/">Vue Shop</v-btn>
<v-spacer></v-spacer>
<v-btn text to="/cart">
<v-badge v-if="totalItems.count" :content="totalItems.count"><v-icon>mdi-cart</v-icon></v-badge>
</v-btn>
</v-app-bar>
<v-main>
<router-view></router-view>
</v-main>
</v-app>
</template>
<script>
export default {
name: 'App',
components: {
},
computed: {
totalItems(){
return this.$store.getters.totalItems
}
}
};
</script>
Upon loading the site, I notice that the computed property is being calculated properly. However, upon clicking the 'Add to' button on the Home.vue file mentioned below:
- It should call the addToCart method.
- This method dispatches the addToCart action from the store.
- Where I calculate the totalItems and update the value using the setTotalItems mutation.
The problem I'm encountering is that when I click the 'Add to' button, I see the totalItems value updating in localStorage but it does not reflect in the v-app-bar component immediately. It only updates if I navigate to a different page and then return to the main page.
Initially, I stored the value in the state instead of localStorage, and it reflected correctly without needing to navigate to another page.
Is there a way to achieve this while still utilizing localStorage instead of the store?
<template>
<v-container>
<v-row>
<v-col v-for="product in products" :key="product.id">
<v-card width="300" height="300">
<v-img :src=product.imgUrl width="300" height="200"></v-img>
<v-card-title>
{{ product.name }}
</v-card-title>
<v-card-text>
${{ product.price }}
<v-btn small class="ml-16 primary" @click="addToCart(product.id)">Add to <v-icon>mdi-cart</v-icon></v-btn>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
name: 'Home',
components: {
},
computed: {
products(){
return this.$store.getters.products
},
cart(){
return this.$store.getters.cart
}
},
methods: {
addToCart(id){
this.$store.dispatch('addToCart', id)
}
}
}
</script>