JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
<filter-select
v-for="(n, i) in filters"
v-model="n.value"
:options="filterOptions[i]"
:name="n.name"
></filter-select>
<button @click="resetFilters">reset</button>
<table>
<thead>
<tr>
<th>id</th>
<th>first name</th>
<th>surname</th>
<th>country</th>
</tr>
</thead>
<tbody>
<tr v-for="n in filteredPersons">
<td>{{ n.id }}</td>
<td>{{ n.name.firstname }}</td>
<td>{{ n.name.surname }}</td>
<td>{{ n.country }}</td>
</tr>
</tbody>
</table>
</div>
CSS
table {
margin: 10px;
}
th, td {
padding: 5px 10px;
border: 1px solid silver;
}
th {
background: #eee;
}
.filter {
margin: 5px;
}
JavaScript
Vue.component('filter-select', {
props: [ 'name', 'options', 'value' ],
template: `
<label class="filter">
{{ name }}:
<select :value="value" @change="$emit('input', $event.target.value)">
<option value="">-------</option>
<option v-for="n in options">{{ n }}</option>
</select>
</label>`
});
new Vue({
el: '#app',
data: () => ({
filters: [
{ name: 'Surname', value: '', getter: obj => obj.name.surname },
{ name: 'Country', value: '', getter: obj => obj.country },
],
persons: [
{ name: { firstname: 'John', surname: 'Smith' }, country: 'USA' },
{ name: { firstname: 'Jane', surname: 'Smith' }, country: 'UK' },
{ name: { firstname: 'Nick', surname: 'Right' }, country: 'USA' },
{ name: { firstname: 'Kevin', surname: 'Smith' }, country: 'USA' },
{ name: { firstname: 'Mary', surname: 'Jones' }, country: 'USA' },
{ name: { firstname: 'Brad', surname: 'Smith' }, country: 'UK' },
{ name: { firstname: 'Helen', surname: 'Jones' }, country: 'USA' },
].map((n, i) => (n.id = i + 1, n)),
}),
methods: {
resetFilters() {
this.filters.forEach(n => n.value = '');
},
},
computed: {
filterOptions() {
return this.filters.map(n => [...new Set(this.persons.map(n.getter))]);
},
filteredPersons() {
return this.filters.reduce((persons, { value, getter }) => {
return value
? persons.filter(n => getter(n) === value)
: persons;
}, this.persons);
},
},
});