I have my vue application using:
component-parent component that is made of component-child
inside component-parent I have buttons, when someone click a button I want to emit an event in order to be handled by vue and passed to another component
What I did so far:
var vm = new Vue({
el: '#app',
methods: {
itemSelectedListener: function(item){
console.log('itemSelectedListener', item);
}
}
});
Vue.component('component-child', {
template: ' <span v-on:click="chooseItem(pty )" >Button </span>',
methods: {
chooseItem: function(pty){
console.log(pty);
this.$emit('itemSelected', {
'priority' : pty
});
}
}
});
Vue.component('component-parent', {
template: '<component-child v-for="q in items" ></component-child>'
});
HTML:
<component-parent v-on:itemSelected="itemSelectedListener" ></component-parent>
It reaches my console.log(pty); line but it seems that this.$emit('itemSelected' wont get through:
console.log('itemSelectedListener', item); // this is not going to be called...
an hint?
should I bubble up the event from child->parent->Vue-instance? ( I also tried that but with no success)
Advertisement
Answer
There is one issue with your component-parent template as it tries to render multiple child components. Vue usually requires a single root div inside components therefore you need to wrap it in a div or other tag.
<div>
<component-child v-for="q in items"></component-child>
</div>
A second thing to point out is that you emit an event from a child component which is 2 levels down and you listen to it in the root.
Root //but you listen to the event up here 1 level above Component 1 //you should listen to the event here Component 2 //your try to emit it from here
You have 2 options here. Either emit from component-child listen to that event in component-parent then propagate that event upwards. Fiddle https://jsfiddle.net/bjqwh74t/29/
The second option would be to register a global so called bus which is an empty vue instance that you can use for such cases when you want communication between non child-parent components. Fiddle https://jsfiddle.net/bjqwh74t/30/
Usually between parent and child components you use the events directly by emitting from child and listening in parent with v-on:event-name="handler" but for cases where you have more levels between components you use the second approach.
Doc link for the first case: https://v2.vuejs.org/v2/guide/components.html#Using-v-on-with-Custom-Events
Doc link for the second case: https://v2.vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication
PS: prefer using kebab-case for event names which means you write with - instead of capital letters. Writing with capital letters can result in weird situations where your event is not caught in the root.