VueJs 2.0 emit event from grand child to his grand parent component
up vote
36
down vote
favorite
It seems that Vue.js 2.0 doesn't emit events from a grand child to his grand parent component.
Vue.component('parent', {
template: '<div>I am the parent - {{ action }} <child @eventtriggered="performAction"></child></div>',
data(){
return {
action: 'No action'
}
},
methods: {
performAction() { this.action = 'actionDone' }
}
})
Vue.component('child', {
template: '<div>I am the child <grand-child></grand-child></div>'
})
Vue.component('grand-child', {
template: '<div>I am the grand-child <button @click="doEvent">Do Event</button></div>',
methods: {
doEvent() { this.$emit('eventtriggered') }
}
})
new Vue({
el: '#app'
})
This JsFiddle solves the issue https://jsfiddle.net/y5dvkqbd/4/ , but by emtting two events:
- One from grand child to middle component
- Then emitting again from middle component to grand parent
Adding this middle event seems repetitive and unneccessary. Is there a way to emit directly to grand parent that I am not aware of?
javascript vuejs2 vue.js
add a comment |
up vote
36
down vote
favorite
It seems that Vue.js 2.0 doesn't emit events from a grand child to his grand parent component.
Vue.component('parent', {
template: '<div>I am the parent - {{ action }} <child @eventtriggered="performAction"></child></div>',
data(){
return {
action: 'No action'
}
},
methods: {
performAction() { this.action = 'actionDone' }
}
})
Vue.component('child', {
template: '<div>I am the child <grand-child></grand-child></div>'
})
Vue.component('grand-child', {
template: '<div>I am the grand-child <button @click="doEvent">Do Event</button></div>',
methods: {
doEvent() { this.$emit('eventtriggered') }
}
})
new Vue({
el: '#app'
})
This JsFiddle solves the issue https://jsfiddle.net/y5dvkqbd/4/ , but by emtting two events:
- One from grand child to middle component
- Then emitting again from middle component to grand parent
Adding this middle event seems repetitive and unneccessary. Is there a way to emit directly to grand parent that I am not aware of?
javascript vuejs2 vue.js
add a comment |
up vote
36
down vote
favorite
up vote
36
down vote
favorite
It seems that Vue.js 2.0 doesn't emit events from a grand child to his grand parent component.
Vue.component('parent', {
template: '<div>I am the parent - {{ action }} <child @eventtriggered="performAction"></child></div>',
data(){
return {
action: 'No action'
}
},
methods: {
performAction() { this.action = 'actionDone' }
}
})
Vue.component('child', {
template: '<div>I am the child <grand-child></grand-child></div>'
})
Vue.component('grand-child', {
template: '<div>I am the grand-child <button @click="doEvent">Do Event</button></div>',
methods: {
doEvent() { this.$emit('eventtriggered') }
}
})
new Vue({
el: '#app'
})
This JsFiddle solves the issue https://jsfiddle.net/y5dvkqbd/4/ , but by emtting two events:
- One from grand child to middle component
- Then emitting again from middle component to grand parent
Adding this middle event seems repetitive and unneccessary. Is there a way to emit directly to grand parent that I am not aware of?
javascript vuejs2 vue.js
It seems that Vue.js 2.0 doesn't emit events from a grand child to his grand parent component.
Vue.component('parent', {
template: '<div>I am the parent - {{ action }} <child @eventtriggered="performAction"></child></div>',
data(){
return {
action: 'No action'
}
},
methods: {
performAction() { this.action = 'actionDone' }
}
})
Vue.component('child', {
template: '<div>I am the child <grand-child></grand-child></div>'
})
Vue.component('grand-child', {
template: '<div>I am the grand-child <button @click="doEvent">Do Event</button></div>',
methods: {
doEvent() { this.$emit('eventtriggered') }
}
})
new Vue({
el: '#app'
})
This JsFiddle solves the issue https://jsfiddle.net/y5dvkqbd/4/ , but by emtting two events:
- One from grand child to middle component
- Then emitting again from middle component to grand parent
Adding this middle event seems repetitive and unneccessary. Is there a way to emit directly to grand parent that I am not aware of?
javascript vuejs2 vue.js
javascript vuejs2 vue.js
asked Mar 5 '17 at 23:45
BassMHL
1,84912341
1,84912341
add a comment |
add a comment |
5 Answers
5
active
oldest
votes
up vote
20
down vote
accepted
The Vue community generally favors using Vuex to solve this kind of issue. Changes are made to Vuex state and the DOM representation just flows from that, eliminating the need for events in many cases.
Barring that, re-emitting would probably be the next best choice, and lastly you might choose to use an event bus as detailed in the other highly voted answer to this question.
The answer below is my original answer to this question and is not an approach I would take now, having more experience with Vue.
This is a case where I might disagree with Vue's design choice and resort to DOM.
In grand-child
,
methods: {
doEvent() {
try {
this.$el.dispatchEvent(new Event("eventtriggered"));
} catch (e) {
// handle IE not supporting Event constructor
var evt = document.createEvent("Event");
evt.initEvent("eventtriggered", true, false);
this.$el.dispatchEvent(evt);
}
}
}
and in parent
,
mounted(){
this.$el.addEventListener("eventtriggered", () => this.performAction())
}
Otherwise, yes, you have to re-emit, or use a bus.
Note: I added code in the doEvent method to handle IE; that code could be extracted in a reusable way.
This behaves differently for IE? wasn't aware there were browser discrepancies with vue...
– BassMHL
Mar 7 '17 at 22:39
@BassemLhm Vue is fine with IE. The problem with IE is not Vue, it's this is a DOM solution and you cannot do new Event() in IE. You have to document.createEvent(). I can add the IE support if needed.
– Bert
Mar 7 '17 at 22:45
add a comment |
up vote
16
down vote
Yes, you're correct events only go from child to parent. They don't go further, e.g. from child to grandparent.
The Vue documentation (briefly) addresses this situation in the Non Parent-Child Communication section.
The general idea is that in the grandparent component you create an empty Vue
component that is passed from grandparent down to the children and grandchildren via props. The grandparent then listens for events and grandchildren emit events on that "event bus".
Some applications use a global event bus instead of a per-component event bus. Using a global event bus means you will need to have unique event names or namespacing so events don't clash between different components.
Here is an example of how to implement a simple global event bus.
add a comment |
up vote
6
down vote
Another solution will be:
Uses vm.$root.$emit
in grand-child, then uses vm.$root.$on
at the ancestor (or anywhere you'd like).
Vue.component('parent', {
template: '<div>I am the parent - {{ action }} <child @eventtriggered="performAction"></child></div>',
data(){
return {
action: 'No action'
}
},
created: function () {
this.$root.$on('eventtriggered1', () => {
this.performAction()
})
},
methods: {
performAction() { this.action = 'actionDone' }
}
})
Vue.component('child', {
template: '<div>I am the child <grand-child @eventtriggered="doEvent"></grand-child></div>',
methods: {
doEvent() {
//this.$emit('eventtriggered')
}
}
})
Vue.component('grand-child', {
template: '<div>I am the grand-child <button @click="doEvent">Do Event</button></div>',
methods: {
doEvent() { this.$root.$emit('eventtriggered1') }
}
})
new Vue({
el: '#app'
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<parent></parent>
</div>
Most elegant solution to me.
– Ovilia
Sep 22 at 7:27
add a comment |
up vote
3
down vote
NEW ANSWER (Nov-2018 update)
I discovered that we could actually do this by leveraging the $parent
property in the grand child component:
this.$parent.$emit("submit", {somekey: somevalue})
Much cleaner and simpler.
Note that this only works if the relationship is child -> grandparent. This does not work if the child can be nested arbitrary levels deep.
– Qtax
Dec 4 at 17:31
add a comment |
up vote
0
down vote
This is the only case when I use event bus!! For passing data from deep nested child, to not directly parent, communication.
First: Create a js file (I name it eventbus.js) with this content:
import Vue from 'vue'
Vue.prototype.$event = new Vue()
Second: In your child component emit an event:
this.$event.$emit('event_name', 'data to pass')
Third: In the parent listen to that event:
this.$event.$on('event_name', (data) => {
console.log(data)
})
Note: If you don't want that event anymore please unregister it:
this.$event.$off('event_name')
INFO: No need to read the below personal opinion
I don't like to use vuex for grand-child to grand-parent communication (Or similar communication level).
In vue.js for passing data from grand-parent to grand-child you can use provide/inject. But there is not something similar for the opposite thing. (grand-child to grand-parent) So I use event bus whenever I have to do that kind of communication.
add a comment |
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
20
down vote
accepted
The Vue community generally favors using Vuex to solve this kind of issue. Changes are made to Vuex state and the DOM representation just flows from that, eliminating the need for events in many cases.
Barring that, re-emitting would probably be the next best choice, and lastly you might choose to use an event bus as detailed in the other highly voted answer to this question.
The answer below is my original answer to this question and is not an approach I would take now, having more experience with Vue.
This is a case where I might disagree with Vue's design choice and resort to DOM.
In grand-child
,
methods: {
doEvent() {
try {
this.$el.dispatchEvent(new Event("eventtriggered"));
} catch (e) {
// handle IE not supporting Event constructor
var evt = document.createEvent("Event");
evt.initEvent("eventtriggered", true, false);
this.$el.dispatchEvent(evt);
}
}
}
and in parent
,
mounted(){
this.$el.addEventListener("eventtriggered", () => this.performAction())
}
Otherwise, yes, you have to re-emit, or use a bus.
Note: I added code in the doEvent method to handle IE; that code could be extracted in a reusable way.
This behaves differently for IE? wasn't aware there were browser discrepancies with vue...
– BassMHL
Mar 7 '17 at 22:39
@BassemLhm Vue is fine with IE. The problem with IE is not Vue, it's this is a DOM solution and you cannot do new Event() in IE. You have to document.createEvent(). I can add the IE support if needed.
– Bert
Mar 7 '17 at 22:45
add a comment |
up vote
20
down vote
accepted
The Vue community generally favors using Vuex to solve this kind of issue. Changes are made to Vuex state and the DOM representation just flows from that, eliminating the need for events in many cases.
Barring that, re-emitting would probably be the next best choice, and lastly you might choose to use an event bus as detailed in the other highly voted answer to this question.
The answer below is my original answer to this question and is not an approach I would take now, having more experience with Vue.
This is a case where I might disagree with Vue's design choice and resort to DOM.
In grand-child
,
methods: {
doEvent() {
try {
this.$el.dispatchEvent(new Event("eventtriggered"));
} catch (e) {
// handle IE not supporting Event constructor
var evt = document.createEvent("Event");
evt.initEvent("eventtriggered", true, false);
this.$el.dispatchEvent(evt);
}
}
}
and in parent
,
mounted(){
this.$el.addEventListener("eventtriggered", () => this.performAction())
}
Otherwise, yes, you have to re-emit, or use a bus.
Note: I added code in the doEvent method to handle IE; that code could be extracted in a reusable way.
This behaves differently for IE? wasn't aware there were browser discrepancies with vue...
– BassMHL
Mar 7 '17 at 22:39
@BassemLhm Vue is fine with IE. The problem with IE is not Vue, it's this is a DOM solution and you cannot do new Event() in IE. You have to document.createEvent(). I can add the IE support if needed.
– Bert
Mar 7 '17 at 22:45
add a comment |
up vote
20
down vote
accepted
up vote
20
down vote
accepted
The Vue community generally favors using Vuex to solve this kind of issue. Changes are made to Vuex state and the DOM representation just flows from that, eliminating the need for events in many cases.
Barring that, re-emitting would probably be the next best choice, and lastly you might choose to use an event bus as detailed in the other highly voted answer to this question.
The answer below is my original answer to this question and is not an approach I would take now, having more experience with Vue.
This is a case where I might disagree with Vue's design choice and resort to DOM.
In grand-child
,
methods: {
doEvent() {
try {
this.$el.dispatchEvent(new Event("eventtriggered"));
} catch (e) {
// handle IE not supporting Event constructor
var evt = document.createEvent("Event");
evt.initEvent("eventtriggered", true, false);
this.$el.dispatchEvent(evt);
}
}
}
and in parent
,
mounted(){
this.$el.addEventListener("eventtriggered", () => this.performAction())
}
Otherwise, yes, you have to re-emit, or use a bus.
Note: I added code in the doEvent method to handle IE; that code could be extracted in a reusable way.
The Vue community generally favors using Vuex to solve this kind of issue. Changes are made to Vuex state and the DOM representation just flows from that, eliminating the need for events in many cases.
Barring that, re-emitting would probably be the next best choice, and lastly you might choose to use an event bus as detailed in the other highly voted answer to this question.
The answer below is my original answer to this question and is not an approach I would take now, having more experience with Vue.
This is a case where I might disagree with Vue's design choice and resort to DOM.
In grand-child
,
methods: {
doEvent() {
try {
this.$el.dispatchEvent(new Event("eventtriggered"));
} catch (e) {
// handle IE not supporting Event constructor
var evt = document.createEvent("Event");
evt.initEvent("eventtriggered", true, false);
this.$el.dispatchEvent(evt);
}
}
}
and in parent
,
mounted(){
this.$el.addEventListener("eventtriggered", () => this.performAction())
}
Otherwise, yes, you have to re-emit, or use a bus.
Note: I added code in the doEvent method to handle IE; that code could be extracted in a reusable way.
edited Jan 8 at 15:32
answered Mar 6 '17 at 0:40
Bert
43k66279
43k66279
This behaves differently for IE? wasn't aware there were browser discrepancies with vue...
– BassMHL
Mar 7 '17 at 22:39
@BassemLhm Vue is fine with IE. The problem with IE is not Vue, it's this is a DOM solution and you cannot do new Event() in IE. You have to document.createEvent(). I can add the IE support if needed.
– Bert
Mar 7 '17 at 22:45
add a comment |
This behaves differently for IE? wasn't aware there were browser discrepancies with vue...
– BassMHL
Mar 7 '17 at 22:39
@BassemLhm Vue is fine with IE. The problem with IE is not Vue, it's this is a DOM solution and you cannot do new Event() in IE. You have to document.createEvent(). I can add the IE support if needed.
– Bert
Mar 7 '17 at 22:45
This behaves differently for IE? wasn't aware there were browser discrepancies with vue...
– BassMHL
Mar 7 '17 at 22:39
This behaves differently for IE? wasn't aware there were browser discrepancies with vue...
– BassMHL
Mar 7 '17 at 22:39
@BassemLhm Vue is fine with IE. The problem with IE is not Vue, it's this is a DOM solution and you cannot do new Event() in IE. You have to document.createEvent(). I can add the IE support if needed.
– Bert
Mar 7 '17 at 22:45
@BassemLhm Vue is fine with IE. The problem with IE is not Vue, it's this is a DOM solution and you cannot do new Event() in IE. You have to document.createEvent(). I can add the IE support if needed.
– Bert
Mar 7 '17 at 22:45
add a comment |
up vote
16
down vote
Yes, you're correct events only go from child to parent. They don't go further, e.g. from child to grandparent.
The Vue documentation (briefly) addresses this situation in the Non Parent-Child Communication section.
The general idea is that in the grandparent component you create an empty Vue
component that is passed from grandparent down to the children and grandchildren via props. The grandparent then listens for events and grandchildren emit events on that "event bus".
Some applications use a global event bus instead of a per-component event bus. Using a global event bus means you will need to have unique event names or namespacing so events don't clash between different components.
Here is an example of how to implement a simple global event bus.
add a comment |
up vote
16
down vote
Yes, you're correct events only go from child to parent. They don't go further, e.g. from child to grandparent.
The Vue documentation (briefly) addresses this situation in the Non Parent-Child Communication section.
The general idea is that in the grandparent component you create an empty Vue
component that is passed from grandparent down to the children and grandchildren via props. The grandparent then listens for events and grandchildren emit events on that "event bus".
Some applications use a global event bus instead of a per-component event bus. Using a global event bus means you will need to have unique event names or namespacing so events don't clash between different components.
Here is an example of how to implement a simple global event bus.
add a comment |
up vote
16
down vote
up vote
16
down vote
Yes, you're correct events only go from child to parent. They don't go further, e.g. from child to grandparent.
The Vue documentation (briefly) addresses this situation in the Non Parent-Child Communication section.
The general idea is that in the grandparent component you create an empty Vue
component that is passed from grandparent down to the children and grandchildren via props. The grandparent then listens for events and grandchildren emit events on that "event bus".
Some applications use a global event bus instead of a per-component event bus. Using a global event bus means you will need to have unique event names or namespacing so events don't clash between different components.
Here is an example of how to implement a simple global event bus.
Yes, you're correct events only go from child to parent. They don't go further, e.g. from child to grandparent.
The Vue documentation (briefly) addresses this situation in the Non Parent-Child Communication section.
The general idea is that in the grandparent component you create an empty Vue
component that is passed from grandparent down to the children and grandchildren via props. The grandparent then listens for events and grandchildren emit events on that "event bus".
Some applications use a global event bus instead of a per-component event bus. Using a global event bus means you will need to have unique event names or namespacing so events don't clash between different components.
Here is an example of how to implement a simple global event bus.
answered Mar 6 '17 at 0:10
Sly_cardinal
8,37333437
8,37333437
add a comment |
add a comment |
up vote
6
down vote
Another solution will be:
Uses vm.$root.$emit
in grand-child, then uses vm.$root.$on
at the ancestor (or anywhere you'd like).
Vue.component('parent', {
template: '<div>I am the parent - {{ action }} <child @eventtriggered="performAction"></child></div>',
data(){
return {
action: 'No action'
}
},
created: function () {
this.$root.$on('eventtriggered1', () => {
this.performAction()
})
},
methods: {
performAction() { this.action = 'actionDone' }
}
})
Vue.component('child', {
template: '<div>I am the child <grand-child @eventtriggered="doEvent"></grand-child></div>',
methods: {
doEvent() {
//this.$emit('eventtriggered')
}
}
})
Vue.component('grand-child', {
template: '<div>I am the grand-child <button @click="doEvent">Do Event</button></div>',
methods: {
doEvent() { this.$root.$emit('eventtriggered1') }
}
})
new Vue({
el: '#app'
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<parent></parent>
</div>
Most elegant solution to me.
– Ovilia
Sep 22 at 7:27
add a comment |
up vote
6
down vote
Another solution will be:
Uses vm.$root.$emit
in grand-child, then uses vm.$root.$on
at the ancestor (or anywhere you'd like).
Vue.component('parent', {
template: '<div>I am the parent - {{ action }} <child @eventtriggered="performAction"></child></div>',
data(){
return {
action: 'No action'
}
},
created: function () {
this.$root.$on('eventtriggered1', () => {
this.performAction()
})
},
methods: {
performAction() { this.action = 'actionDone' }
}
})
Vue.component('child', {
template: '<div>I am the child <grand-child @eventtriggered="doEvent"></grand-child></div>',
methods: {
doEvent() {
//this.$emit('eventtriggered')
}
}
})
Vue.component('grand-child', {
template: '<div>I am the grand-child <button @click="doEvent">Do Event</button></div>',
methods: {
doEvent() { this.$root.$emit('eventtriggered1') }
}
})
new Vue({
el: '#app'
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<parent></parent>
</div>
Most elegant solution to me.
– Ovilia
Sep 22 at 7:27
add a comment |
up vote
6
down vote
up vote
6
down vote
Another solution will be:
Uses vm.$root.$emit
in grand-child, then uses vm.$root.$on
at the ancestor (or anywhere you'd like).
Vue.component('parent', {
template: '<div>I am the parent - {{ action }} <child @eventtriggered="performAction"></child></div>',
data(){
return {
action: 'No action'
}
},
created: function () {
this.$root.$on('eventtriggered1', () => {
this.performAction()
})
},
methods: {
performAction() { this.action = 'actionDone' }
}
})
Vue.component('child', {
template: '<div>I am the child <grand-child @eventtriggered="doEvent"></grand-child></div>',
methods: {
doEvent() {
//this.$emit('eventtriggered')
}
}
})
Vue.component('grand-child', {
template: '<div>I am the grand-child <button @click="doEvent">Do Event</button></div>',
methods: {
doEvent() { this.$root.$emit('eventtriggered1') }
}
})
new Vue({
el: '#app'
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<parent></parent>
</div>
Another solution will be:
Uses vm.$root.$emit
in grand-child, then uses vm.$root.$on
at the ancestor (or anywhere you'd like).
Vue.component('parent', {
template: '<div>I am the parent - {{ action }} <child @eventtriggered="performAction"></child></div>',
data(){
return {
action: 'No action'
}
},
created: function () {
this.$root.$on('eventtriggered1', () => {
this.performAction()
})
},
methods: {
performAction() { this.action = 'actionDone' }
}
})
Vue.component('child', {
template: '<div>I am the child <grand-child @eventtriggered="doEvent"></grand-child></div>',
methods: {
doEvent() {
//this.$emit('eventtriggered')
}
}
})
Vue.component('grand-child', {
template: '<div>I am the grand-child <button @click="doEvent">Do Event</button></div>',
methods: {
doEvent() { this.$root.$emit('eventtriggered1') }
}
})
new Vue({
el: '#app'
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<parent></parent>
</div>
Vue.component('parent', {
template: '<div>I am the parent - {{ action }} <child @eventtriggered="performAction"></child></div>',
data(){
return {
action: 'No action'
}
},
created: function () {
this.$root.$on('eventtriggered1', () => {
this.performAction()
})
},
methods: {
performAction() { this.action = 'actionDone' }
}
})
Vue.component('child', {
template: '<div>I am the child <grand-child @eventtriggered="doEvent"></grand-child></div>',
methods: {
doEvent() {
//this.$emit('eventtriggered')
}
}
})
Vue.component('grand-child', {
template: '<div>I am the grand-child <button @click="doEvent">Do Event</button></div>',
methods: {
doEvent() { this.$root.$emit('eventtriggered1') }
}
})
new Vue({
el: '#app'
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<parent></parent>
</div>
Vue.component('parent', {
template: '<div>I am the parent - {{ action }} <child @eventtriggered="performAction"></child></div>',
data(){
return {
action: 'No action'
}
},
created: function () {
this.$root.$on('eventtriggered1', () => {
this.performAction()
})
},
methods: {
performAction() { this.action = 'actionDone' }
}
})
Vue.component('child', {
template: '<div>I am the child <grand-child @eventtriggered="doEvent"></grand-child></div>',
methods: {
doEvent() {
//this.$emit('eventtriggered')
}
}
})
Vue.component('grand-child', {
template: '<div>I am the grand-child <button @click="doEvent">Do Event</button></div>',
methods: {
doEvent() { this.$root.$emit('eventtriggered1') }
}
})
new Vue({
el: '#app'
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<parent></parent>
</div>
answered Aug 2 at 20:24
Sphinx
5,41521228
5,41521228
Most elegant solution to me.
– Ovilia
Sep 22 at 7:27
add a comment |
Most elegant solution to me.
– Ovilia
Sep 22 at 7:27
Most elegant solution to me.
– Ovilia
Sep 22 at 7:27
Most elegant solution to me.
– Ovilia
Sep 22 at 7:27
add a comment |
up vote
3
down vote
NEW ANSWER (Nov-2018 update)
I discovered that we could actually do this by leveraging the $parent
property in the grand child component:
this.$parent.$emit("submit", {somekey: somevalue})
Much cleaner and simpler.
Note that this only works if the relationship is child -> grandparent. This does not work if the child can be nested arbitrary levels deep.
– Qtax
Dec 4 at 17:31
add a comment |
up vote
3
down vote
NEW ANSWER (Nov-2018 update)
I discovered that we could actually do this by leveraging the $parent
property in the grand child component:
this.$parent.$emit("submit", {somekey: somevalue})
Much cleaner and simpler.
Note that this only works if the relationship is child -> grandparent. This does not work if the child can be nested arbitrary levels deep.
– Qtax
Dec 4 at 17:31
add a comment |
up vote
3
down vote
up vote
3
down vote
NEW ANSWER (Nov-2018 update)
I discovered that we could actually do this by leveraging the $parent
property in the grand child component:
this.$parent.$emit("submit", {somekey: somevalue})
Much cleaner and simpler.
NEW ANSWER (Nov-2018 update)
I discovered that we could actually do this by leveraging the $parent
property in the grand child component:
this.$parent.$emit("submit", {somekey: somevalue})
Much cleaner and simpler.
answered Nov 7 at 16:30
BassMHL
1,84912341
1,84912341
Note that this only works if the relationship is child -> grandparent. This does not work if the child can be nested arbitrary levels deep.
– Qtax
Dec 4 at 17:31
add a comment |
Note that this only works if the relationship is child -> grandparent. This does not work if the child can be nested arbitrary levels deep.
– Qtax
Dec 4 at 17:31
Note that this only works if the relationship is child -> grandparent. This does not work if the child can be nested arbitrary levels deep.
– Qtax
Dec 4 at 17:31
Note that this only works if the relationship is child -> grandparent. This does not work if the child can be nested arbitrary levels deep.
– Qtax
Dec 4 at 17:31
add a comment |
up vote
0
down vote
This is the only case when I use event bus!! For passing data from deep nested child, to not directly parent, communication.
First: Create a js file (I name it eventbus.js) with this content:
import Vue from 'vue'
Vue.prototype.$event = new Vue()
Second: In your child component emit an event:
this.$event.$emit('event_name', 'data to pass')
Third: In the parent listen to that event:
this.$event.$on('event_name', (data) => {
console.log(data)
})
Note: If you don't want that event anymore please unregister it:
this.$event.$off('event_name')
INFO: No need to read the below personal opinion
I don't like to use vuex for grand-child to grand-parent communication (Or similar communication level).
In vue.js for passing data from grand-parent to grand-child you can use provide/inject. But there is not something similar for the opposite thing. (grand-child to grand-parent) So I use event bus whenever I have to do that kind of communication.
add a comment |
up vote
0
down vote
This is the only case when I use event bus!! For passing data from deep nested child, to not directly parent, communication.
First: Create a js file (I name it eventbus.js) with this content:
import Vue from 'vue'
Vue.prototype.$event = new Vue()
Second: In your child component emit an event:
this.$event.$emit('event_name', 'data to pass')
Third: In the parent listen to that event:
this.$event.$on('event_name', (data) => {
console.log(data)
})
Note: If you don't want that event anymore please unregister it:
this.$event.$off('event_name')
INFO: No need to read the below personal opinion
I don't like to use vuex for grand-child to grand-parent communication (Or similar communication level).
In vue.js for passing data from grand-parent to grand-child you can use provide/inject. But there is not something similar for the opposite thing. (grand-child to grand-parent) So I use event bus whenever I have to do that kind of communication.
add a comment |
up vote
0
down vote
up vote
0
down vote
This is the only case when I use event bus!! For passing data from deep nested child, to not directly parent, communication.
First: Create a js file (I name it eventbus.js) with this content:
import Vue from 'vue'
Vue.prototype.$event = new Vue()
Second: In your child component emit an event:
this.$event.$emit('event_name', 'data to pass')
Third: In the parent listen to that event:
this.$event.$on('event_name', (data) => {
console.log(data)
})
Note: If you don't want that event anymore please unregister it:
this.$event.$off('event_name')
INFO: No need to read the below personal opinion
I don't like to use vuex for grand-child to grand-parent communication (Or similar communication level).
In vue.js for passing data from grand-parent to grand-child you can use provide/inject. But there is not something similar for the opposite thing. (grand-child to grand-parent) So I use event bus whenever I have to do that kind of communication.
This is the only case when I use event bus!! For passing data from deep nested child, to not directly parent, communication.
First: Create a js file (I name it eventbus.js) with this content:
import Vue from 'vue'
Vue.prototype.$event = new Vue()
Second: In your child component emit an event:
this.$event.$emit('event_name', 'data to pass')
Third: In the parent listen to that event:
this.$event.$on('event_name', (data) => {
console.log(data)
})
Note: If you don't want that event anymore please unregister it:
this.$event.$off('event_name')
INFO: No need to read the below personal opinion
I don't like to use vuex for grand-child to grand-parent communication (Or similar communication level).
In vue.js for passing data from grand-parent to grand-child you can use provide/inject. But there is not something similar for the opposite thing. (grand-child to grand-parent) So I use event bus whenever I have to do that kind of communication.
answered Nov 22 at 16:24
roli roli
2,455817
2,455817
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f42615445%2fvuejs-2-0-emit-event-from-grand-child-to-his-grand-parent-component%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown