Don't put event handlers in the Vuex store. They do not belong there, and they will never work as expected. In the store you have getters (ways of getting values out of your store), mutations (synchronous setters), actions (asynchronous setters) and the state (your data).
Listeners belong on a Vue instance, such as a component. Other than that I would also suggest avoiding this.$root
and this.$parent
like the plague. Having these in your code commonly suggests that you are changing components outside their actual component files, which causes magic behaviour where things change where you do not expect them to change.
In your case what you want to do can much more easily be done with a single store mutation or action.
In your store create a mutation
const mutations = {
showLoading(state, data) {
state.loading = data;
}
};
Now in your component just use this.$store.commit('showLoading', true);
. No event bus needed. No events that magically turn up in the root component. Just a single synchronous setter.
If you need to have global event handling you can instead use a bus.
const $bus = new Vue();
Vue.prototype.$bus = $bus;
In components you can listen to events with this.$bus.$on(...)
or emit events with this.$bus.$emit(...)
. If you need to do stuff outside of Vue entirely, you can create event listeners outside of a component using the following pattern.
$bus.$on('show-loading', (vars) => {
// Do something
});
Technically it would allow you to even load the store with import store from '../path/to/store'
and store.commit(...)
.