How do I propagate a Vue.js event up the component chain?
I have three components.
I have no influence on what the component Datatable
actually calls it from me from npm.
Now I want to send an event from EditButton
to mine Zonelist
.
Zonelist
:
<template>
<datatable :columns="table_columns" :data="table_rows" filterable paginate v-on:remove="removeItem"></datatable>
</template>
<script>
import datatable from 'vuejs-datatable';
import moment from 'moment';
export default {
data() {
return {
table_columns: [
{label: "Zone", component: 'ZoneLink'},
{label: "Last updated", callback (row) {
let locale = $('html').closest('[lang]').attr('lang') || 'en';
moment.locale(locale);
return moment(row.last_updated).format('D. MMM YYYY');
}},
{label: '', component: 'EditButton'}
],
table_rows: [
{
"name": "xyz.de",
"last_updated": "2017-10-21 17:29:50"
}
],
form: {
name: '',
errors: []
}
};
},
components: {
datatable
},
methods: {
removeItem (item) {
this.table_rows.forEach((value, index, array) => {
if (value.name === item) {
Vue.delete(array, index);
}
});
}
}
}
</script>
Now my EditButton
component is an $emit()
event remove
with a parameter.
But nothing happens. So I think vue cannot find the listener.
(I'm using method footnotes from ES6 here)
How could I do this correctly without changing the state Zonelist
through this.$parent.$parent
from EditButton
?
source to share
Passing a non-parent child in Vue is usually handled either through an event bus or state management system.
In this case, unless your application is more complex, an event bus is probably all you need. Since you are using separate file components, you may need to declare the bus in the window, perhaps in your main script.
window.bus = new Vue()
Then in EditButton
you can fire the event
bus.$emit('some-event', someData)
And in yours ZoneList
you can listen to it.
bus.$on('some-event', someData => this.doSomething(someData))
source to share