37

I am used to using a global event bus to handle cross-component methods. For example:

var bus = new Vue();
...
//Component A
bus.$emit('DoSomethingInComponentB');
...
//Component B
bus.$on('DoSomethingInComponentB', function(){ this.doSomething() })

However, I am building a larger project, which requires global state management. Naturally, I want to use Vuex.

While this bus pattern works with Vuex, it seems wrong. I have seen Vuex recommended as a replacement for this pattern.

Is there a way to run methods in components from Vuex? How should I approach this?

3 Answers 3

38

Vuex and event bus are two different things in the sense that vuex manages central state of your application while event bus is used to communicate between different components of your app.

You can execute vuex mutation or actions from a component and also raise events from vuex's actions.

As the docs says:

Actions are similar to mutations, the difference being that:

  • Instead of mutating the state, actions commit mutations.
  • Actions can contain arbitrary asynchronous operations.

So you can raise an event via bus from actions and you can call an action from any component method.

Sign up to request clarification or add additional context in comments.

4 Comments

So using the bus and vuex at the same time is an OK pattern? Seems to contradict what's said in the docs, but I'll roll with it for now :) Thanks!
Yes, in my opinion, you can use both together depending on the use-case. Once can replace all the functionality of event Bus by Vuex, but for a simple use case(communication between two components, trigger method of another component, etc) you can use event bus, while for place where you need one variable by multiple components and all modifying it, you can use vuex.
@Blue_Dragon360 I was struggling with the same problem, then I came across this post which essentially says the same thing as Saurabh. forum.vuejs.org/t/bus-vs-vuex/6679
See this example how they are using both
1

Using a global event bus is an anti pattern because it becomes very difficult to trace it (where was this event fired from? Where else are we listening to it? etc.)

Why do you want to use a global event bus? Is there some method that you want to trigger in another component? If you use Vuex then all your actions (methods) are in one central state and you can just dispatch your action.

So for example instead of doing this..

// Component A
bus.$emit('DoSomethingInComponentB');

// Component B
bus.$on('DoSomethingInComponentB', function(){ this.doSomething() })

With Vuex you would have the doSomething() function in a central store as an action. Then just make sure to convert you local component data to a global Vuex state data and dispatch that action.

this.$store.dispatch('doSomething')

1 Comment

Commenting 4 years later... It could be problematic when the user opens multiple tabs and the action is intended for the current view.
0

It may not be directly what you are looking for, but I use watchers to respond to state changes. I come from an Angular background where having side effects respond to actions makes sense to me. To make this work I am having a particular value in the store change and then watch for the value in the relevant component like so:

Vue.component('comp-2', {
  ...
  watch: {
    mod1Foo() {
      // do something here when the store value of the getter
      // mod1/getFoo changes
    }
  },
  computed: {
    ...mapGetters({
      mod1Foo: 'mod1/getFoo'
    })
  }
});

Here is a full StackBlitz example: https://stackblitz.com/edit/js-gdme1g

1 Comment

thx a lot for this very instructive example

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.