22

I want to emit an event on the root component, and listen to in in the root component. In a child of child component I do this:

this.$root.$emit('access-token', accessToken);

In root component (the top component, first to load) I do this (edit: this is in the mounted() method):

this.$on('access-token', this.setAccessToken);

It doesn't react to the event though. Why?

Mattias
  • 715
  • 1
  • 6
  • 19
  • you tagged this Vue &Vue 2, are you using Vue 2? – Scott Sword May 04 '18 at 19:28
  • Yes, vue2, sorry – Mattias May 04 '18 at 19:34
  • Curious, if you put a listener elsewhere does it work? For instance if you put the listener one level up from where you're emitting it rather than the root does is get triggered properly? I would make sure that you're broadcasting correctly first then dig into your listeners. – Scott Sword May 04 '18 at 19:38
  • Yes it does work elsewhere. – Mattias May 04 '18 at 19:41
  • If I do this.$root.$on in the component where I emit the event, then the handler gets called, but if I add the handler in mounted() in the root component it doesn't work. – Mattias May 04 '18 at 19:46
  • How many layers deep is your nested component? This $root approach is eerily similar to Angular 1. I did just find this article that said Vue emits only go up one level, so you may need to bump up more. https://forum.vuejs.org/t/recommended-approach-to-emit-an-event-from-a-nested-child/10197/2 – Scott Sword May 04 '18 at 19:47
  • Also, from experience in Angular 1, this is exactly why folks use Redux. – Scott Sword May 04 '18 at 19:48

2 Answers2

45

You are not using the $root for the event $on

Change this:

this.$on('access-token', this.setAccessToken); 

for this:

this.$root.$on('access-token', this.setAccessToken);
tk3
  • 990
  • 1
  • 13
  • 18
Andres Garcia
  • 451
  • 3
  • 2
  • 2
    Seems worth mentioning that it appears vue is not encouraging this kind of approach, and suggests a dummy component as an event bus or vuex- https://vuejs.org/v2/guide/migration.html#dispatch-and-broadcast-replaced – chrismarx Jan 09 '19 at 22:09
  • 1
    I am using ```this.$root.$on('map-doc', function(control) { console.log(this.brushSize); //this.addMapControlText(control); });``` in a component's mounted block. Why I am not able to get the value of this.dataElement inside this? – AbhimanuSharma Oct 15 '20 at 06:54
1

I've to use the following approach:

mounted() {
  this.$nuxt.$emit('event-name')
} 
mounted() {
  this.$nuxt.$on('event-name', () =>
    ...
  }
}

Using Nuxt 2.14

Wonderman
  • 931
  • 10
  • 21