Zeth
Zeth

Reputation: 2578

VueJS - Emit event to several components (with varying parents)

I have a bunch of Vue Components like this:

App.js
 |
 |-- CreateTasks
 |
 |-- LatestTasks (lists 20 tasks)
 |
 |-- FooBar
 |   |---LatestTasks (lists 10 tasks)

When making a task in the CreateTasks I would like to emit an event, that is caught in any other LatestTasks-component, so it knows to update the list.

I can't get this to work, though.

Here is my code:

In CreateTasks

  methods: {
    createTask(){
      let task = { name: 'newTask' };
      this.$emit( 'new-task-created' );
    }
  }

In LatestTasks

  methods: {
    getLatestTasks(){
      ...
    }
  }
  created() {
    window.addEventListener('new-task-created', this.getLatestTasks );
  },

Upvotes: 1

Views: 1908

Answers (2)

user120242
user120242

Reputation: 15268

You are better off using Vuex or redux. But if you just want to use events, or it's a quick small app where you just need a quick hack:

Attach events to the root element:

this.$root.$on('myevent',function(data){console.log(data)})

Then emit the events from the root element:

this.$root.$emit('myevent',{data:1234}}

Or create an EventBus:

// eventbus.js
import Vue from 'vue'
const EventBus = new Vue()
export default EventBus

Listen on EventBus:

// component1.js
import Vue from 'vue'
import EventBus from './eventbus'
Vue.component('component1', {
  mounted () {
    EventBus.$on('myevent', function (data) {
       console.log(data)
    });
  }
});

Emit event on EventBus:

// component2.js
import Vue from 'vue'
import EventBus from './eventbus'
Vue.component('component2', {
  methods: {
    emitMethod () {
       EventBus.$emit('myevent', {data: 1234});
    }
  }
});

Upvotes: 2

Nikolay Yankov
Nikolay Yankov

Reputation: 376

For this purpose it's most suitable to use Vuex. Instead of emitting an event in createTask(), you can dispatch() an action to the Vuex store. And in every component which you want to be aware of this data you add a computed property which links to specific Vuex getter.

Vuex Docs

Another option would be to emit an event as you initially proposed, but you'll have to listen for it in the parent component and then to store it in a local variable in that parent component and finally create a prop for each component which will receive the updated newTask.

I hope this helps, if you wish I can give you more detailed example for implementation.

Upvotes: 1

Related Questions