So I working on app in Vue. I have problem with sending and receiving data between components. Already tried with $dispatch/$broadcast
, $emit/$on
but still now working. I want to send selected active_club
from ClubSelection.vue
to vue_main.js
.
Vue version: 2.0.3
Structure of my app:
- vue_main - main Vue file
- HeaderElement.vue (child of vue_main)
- ClubSelection.vue (child of HeaderElement)
- HeaderElement.vue (child of vue_main)
Need to send active_club from ClubSelection to vue_main.
ClubSelection.vue
<script>
export default{
props: [
'club', 'title'
],
created(){
//Get club list
this.$http.get('/api/clubs', function(data) {
this.clubs = data;
console.log(data);
//read active club from parent
this.selected = this.$parent.$parent.active_club;
});
},
data(){
return{
clubs: [],
selected: null,
}
},
watch: {
selected: function(v) {
this.club = v;
//Post to database selected club
this.$http.post('/api/clubs/' + v + '/active')
},
club: function(v) {
this.selected = v;
//Change active_club at parent (THIS NOT WORKING)
// this.$emit('active_club', v);
// this.$parent.active_club = v;
club.$emit('active_club', v);
},
}
}
</script>
vue_main.js
const app = new Vue({
router,
data() {
return {
user: [],
active_club: null,
ranking: null
}
},
created: function() {
var self = this;
this.$http.get('/api/users/me', function(data) {
this.user = data;
self.active_club = data.active_club;
})
}
}).$mount('#app');
const club = new Vue();
//THIS NOT WORKING
club.$on('active_club', function (id) {
alert(id)
this.active_club = id;
});
Errors:
Vue warn]: Error in watcher "club" (found in component )
vue_main.js:16924 Uncaught (in promise) ReferenceError: club is not defined
I have tried many set ups, this is one of them. How to make this working?
$dispatch
and$broadcast
are deprecated in Vue 2.0.In your case, what you need is communication between a parent component and child component. When a child
$emit
s an event, parent can listen to it by providing a method in template markup itself, usingv-on:parentMethod()
as follows:The above markup is done inside parent component's template. And the parent component needs to have that
handlerMethod
in itsmethods
.Here is a sample "parent-child communication" question on Stackoverflow, which has a jsFiddle example also: Delete a Vue child component
You may use the above answer as reference to implement
$emit
in your app.Edit: Additional Notes
I forgot to mention the note about three level hierarchy you have. In your app, you have the following hierarchy:
parent: vue_main
child 1: HeaderElement
child 1.1: ClubSelection
For sending events from ClubSelection to vue_main, you may either use non parent-child communication method or you can relay the event using the intermediate HeaderElement.
Here is how the event relay can work:
$emit
, which is received by HeaderElement usingv-on
.handlerMethod
in HeaderElement does athis.$emit
, which can be received by your main template using anotherv-on
.While the above may look a bit convoluted, it is much more efficient than broadcasting to every single component in the app, as it is generally done in Angualr 1.x or other frameworks.