Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
el: '#app',
data: () => ({
rows: [
{
name: '1-5',
keywords: 'one,two,three,four,five'
},
{
name: '6-10',
keywords: 'six,seven,eight,nine,ten'
},
{
name: '2n + 1',
keywords: 'one,three,five,seven,nine'
},
{
name: '2n',
keywords: 'two,four,six,eight,ten'
},
{
name: '3n + 1',
keywords: 'one,four,seven,ten'
},
{
name: '5n + 2',
keywords: 'two,seven'
}
],
keywords: []
}),
computed: {
renderedRows() {
return this.keywords.length
? this.rows.filter((row) =>
this.keywords.some((kw) => row.keywords.split(',').includes(kw))
)
: this.rows
},
allKeywords() {
return [
...new Set(this.rows.map((row) => row.keywords.split(',')).flat())
]
}
},
methods: {
toggleKeyword(k) {
this.keywords = this.keywords.includes(k)
? this.keywords.filter((kw) => kw !== k)
: [...this.keywords, k]
}
}
})
td {
padding: 3px 7px;
}
button {
cursor: pointer;
margin: 0 2px;
}
button.active {
background-color: #666;
color: white;
border-radius: 3px;
}
button.active:hover {
background-color: #444;
}
<script src="https://unpkg.com/vue@2"></script>
<div id="app">
<h4>Keywords:</h4>
<div>
<button
v-for="key in allKeywords"
:key="key"
v-text="key"
:class="{ active: keywords.includes(key) }"
@click="toggleKeyword(key)"
/>
</div>
<h4>Rows:</h4>
<table>
<thead>
<th>Name</th>
<th>Keywords</th>
</thead>
<tbody>
<tr v-for="row in renderedRows" :key="row.name">
<td v-text="row.name" />
<td>
<button
v-for="key in row.keywords.split(',')"
:key="key"
v-text="key"
:class="{ active: keywords.includes(key) }"
@click="toggleKeyword(key)"
/>
</td>
</tr>
</tbody>
</table>
</div>