I have the following component tree:
App
List
ItemDetails
Widget1
...
List
component has a filters form, those are applied on button pressWidget1
has a button which applies another filter (by id
) to the list, applying that one removes filters from the filter form and vice versav-model
of the filter fields in List
and the actually applied filters (those are in the store)Currently, I've put the following state to the VueX store:
state: {
filters: {
// these come from the List's filter panel
result: '',
name: '',
date: '',
// this one comes from Widget1
id: '',
},
pagination: {
perPage: 10,
page: 0,
total: 0,
},
items: [],
selectedItem: null,
},
and both filters from the List
and from the button in Widget1
are applied via dispatching the following action to the store:
applyFilters ({ state, commit, dispatch }, filters) {
if(filters.id) {
for(let filterName in state.filters)
if(filterName !== 'id')
filters[filterName] = '';
} else {
filters.id = '';
}
commit('setFilters', filters);
commit('setPage', 0);
dispatch('loadExaminations');
},
But here's the problem: the List
component has its model of filter fields (on press of the button those are gathered and applyFilters
is dispatched). This works well except when the id filter (from Widget1) is applied, the filter fields in the List
component are not emptied.
One obvious option to handle this is to move the model of those filter fields to the store as well. That doesn't look that nice since for each field (that uses v-model
) I have to create a computed
(in the List
component) and write a setter and a getter from the store. It seems nicer to send an event from applyFilters
to List
saying "empty the filter fields", but I'm not sure if VueX can do this. Is this possible? Or should I stick with the "move filter fields' model to the store" plan? Or do you know a nice alternative? I'm aware of the event bus concept, but that one uses Vue
instance which shouldn't be used in store, I guess.
You can listen to vuex's actions by using subscribeAction.
// List.vue
mounted() {
this.$store.subscribeAction({
before: (action, state) => {
if (action.type === "applyFilters" && action.payload.id) {
this.emptyComponentFields();
}
},
after: (action, state) => {}
});
}