I am currently working on a web application where each page of the site has 2 JS files: a global "bootstrap.js" file that is consistent across every page and a custom JS file specific to each page. I've run into an issue where I want these files to share a Vuex store, but changes made in one page do not reflect on the other. Does anyone have a solution for sharing a Vuex store across multiple pages?
One example I'm facing involves a shopping cart feature I'm developing. I would like the "bootstrap.js" file to utilize a Vuex store for the cart so that it can display the number of items in the cart on every page. Additionally, on certain individual pages such as the product description page, I want to use the same Vuex cart store to modify the cart contents and have those changes reflected in the "bootstrap.js" file. Here's a snippet of the code:
global_store.jsx:
import Vue from 'vue'
import Vuex from 'vuex'
import { doAsync } from '../utils/ajax'
Vue.use(Vuex)
const GET_CART_ASYNC = {
SUCCESS: 'GET_CART_ASYNC_SUCCESS',
FAILURE: 'GET_CART_ASYNC_FAILURE',
PENDING: 'GET_CART_ASYNC_PENDING',
}
export let cartStore = new Vuex.Store({
state: {
cart: undefined,
loading: false
},
mutations: {
[GET_CART_ASYNC.SUCCESS](state, data) {
Vue.set(state, 'loading', false)
Vue.set(state, 'cart', data)
},
[GET_CART_ASYNC.FAILURE](state) {
Vue.set(state, 'loading', false)
Vue.set(state, 'cart', null)
},
[GET_CART_ASYNC.PENDING](state) {
Vue.set(state, 'loading', true)
Vue.set(state, 'cart', null)
}
},
actions: {
manipulateCart(store, action=null) {
doAsync(store, `/cart/api`, GET_CART_ASYNC, action)
}
}
})
boostrap.jsx:
import Vue from 'vue'
import { mapState } from 'vuex'
import { cartStore } from '../cart/global_store'
cartStoreGlobal.dispatch('manipulateCart')
new Vue({
el: '#cart_display',
store: cartStore,
computed: mapState(['cart']),
render(h) {
if(this.cart === null) {
return
}
var num_items = this.cart.map(cart_item => cart_item.quantity).reduce((accumulator, quantity) => accumulator + quantity, 0)
return (
<p class="navbar-text pull-right" id="mini-cart">
<a class="button right" href="/cart">
<strong>{num_items} items</strong> <span>$0.00</span>
</a>
</p>
)
}
})
cart.jsx
import Vue from 'vue'
import { mapState } from 'vuex'
import { CartView } from '../cart/cart_view'
import { cartStore } from '../cart/global_store'
// TODO: remove this as its already called in bootstrap.jsx, figure out how to use store singletons with webpack
cartStore.dispatch('manipulateCart')
new Vue({
el: '#cart',
store: cartStore,
computed: mapState(['cart']),
render(h) {
return (<CartView
cart={this.cart}
remove_cb={(photo_id_to_remove) => cartStore.dispatch('manipulateCart', [{action: 'set', photo_id: photo_id_to_remove, quantity: 0}])}
></CartView>)
},
})
The global_store contains the store definition and both boostrap and cart components are importing it. The specifics of the "doAsync" function are not critical. I'm still learning about Vue and Vuex, and may not fully grasp how WebPack functions, so any guidance or assistance in making this setup work seamlessly would be greatly appreciated!