I have a VueJS 3 application with two Vue components (.vue files) and Vue 3 Composition API syntax. The first one contains a radio list that will be used to apply a filter to the second component (imported inside the first component) that contains a Vue3 client datatable. This datatable is the Vue3 version of this datatable : https://github.com/matfish2/vue-tables-2.
My goal is to send a filter event (when I click on a radio element) from the parent component to the datatable inside the child component by using the customFilters option of the datatable. This event should apply a custom filter to the data inside v-tables-3 according to the value of the selected radio button.
Note that the custom event is passed from parent to child using Vue 3 props.
According to the columnFilters documentation, I can add a customFilters inside the datatable options by doing something like that:
customFilters: [{
name: 'alphabet',
callback: function(row, query) {
return row.name[0] == query;
}
}]
and then emit the event using either
Event.$emit('vue-tables.filter::alphabet', query);
or (Vue 3 version)
EventBus.emit('vue-tables.filter::alphabet', query);
I tried to apply the same function as the documentation, but I never managed to make it works.
I then tried to use Mitt directly to try passing an event from a component to another.
I can emit an event from the parent to the child and display the content of the query, but only by hard coding emitter.on(event_name, e=> console.log(e)
inside the OnMounted function, and it doesn't looks like the thing to do (it is not written in the documentation). Moreover, the customFilter is completly ignored.
my main.js file :
import { createApp } from "vue";
import App from "./App.vue";
const app = createApp(App);
// datatables
import { ClientTable, EventBus } from "v-tables-3";
// Mitt
import mitt from 'mitt';
const emitter = mitt();
app.config.globalProperties.emitter = mitt();
app.use(ClientTable).use(EventBus).use(emitter).mount("#app");
my parent Vue component :
<template>
<div class="col-2 layout-spacing">
<div class="radio-classic radio-primary mb-3 custom-control custom-radio">
<input type="radio" class="custom-control-input" id="radio_id_1" name="radio_name" value="value_1" required @change="refreshDatatable($event)"/>
<label class="custom-control-label" :for="radio_id_1">Value 1</label>
</div>
<div class="radio-classic radio-primary mb-3 custom-control custom-radio">
<input type="radio" class="custom-control-input" id="radio_id_2" name="radio_name" value="value_2" required @change="refreshDatatable($event)"/>
<label class="custom-control-label" :for="radio_id_2">Value 2</label>
</div>
<!-- More radio inputs -->
/>
</div>
<div class="col-10 layout-spacing">
<datatable v-bind:custom_filters="family_filters"/>
</div>
</template>
<script setup>
import { getCurrentInstance } from 'vue';
import { EventBus } from 'v-tables-3';
import datatable from './child_component.vue';
const internalInstance = getCurrentInstance();
const emitter = internalInstance.appContext.config.globalProperties.emitter;
const family_filters = [{
name: 'fa_filter',
callback: function (row, query) {
return row.name[0] == query;
}
}];
const refreshDatatable = (event) => {
emitter.emit('fa_filter_mitt', event.target.value); // Mitt version
EventBus.emit('vue-tables.filter::fa_filter', event.target.value); // v-tables EventBus version
}
</script>
my child component
<template>
<v-client-table :data="items" :columns="columns" :options="table_option"/>
</template>
<!-- Get props from parent Component -->
<script>
export default {
props: ['custom_filters'],
};
</script>
<script setup>
import { onMounted, getCurrentInstance } from 'vue';
import { EventBus } from 'v-tables-3';
const internalInstance = getCurrentInstance();
const emitter = internalInstance.appContext.config.globalProperties.emitter;
const table_option = ref({
(...)
customFilters: __props.custom_filters === undefined ? [] : __props.custom_filters,
});
onMounted(() => {
emitter.on('fa_filter_mitt', e=> console.log('test Mitt : ', e));
EventBus.on('vue-tables.filter::fa_filter', e=> console.log('test datatable EventBus : ', e));
});
</script>
How can I have the event transmitted from parent to child ?
Note that emitter only contains the 'fa_filter_mitt' event and nothing else, the customFilters option seems ignored.