Vue filtering list
Add/remove items from an array Filter array
by Compay
HTML
<div id="app">
<h2>Filters:</h2>
<ol>
<li v-for="filter in possibleFilters" :key="filter">
<label>
<input type="checkbox"
@change="toggleFilter(filter)"
:checked="filters.includes(filter)">
<span>{{ filter }}</span>
</label>
</li>
</ol>
<hr>
<h2>Products:</h2>
<ol>
<li v-for="product in matchedAndSortedProducts" :key="product.title">{{ product.title }}</li>
</ol>
</div>
CSS
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
hr {
margin: 24px 0;
}
li {
margin: 8px 0;
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
del {
color: rgba(0, 0, 0, 0.3);
}
Vue
new Vue({
el: "#app",
data: {
filters: [],
products: [
{ title: "3 Bedroom Apartment", topic: "Houses" },
{ title: "Renault Scenic", topic: "Cars" },
{ title: "Mazda 6", topic: "Cars" },
{ title: "Childish Tycoon", topic: "Boats" },
{ title: "RMS Lusitania", topic: "Boats" },
{ title: "HMS Beagle", topic: "Boats" }
]
},
methods: {
toggleFilter: function (newFilter) {
this.filters = !this.filters.includes(newFilter)
? [...this.filters, newFilter]
: this.filters.filter(filter => filter !== newFilter)
}
},
computed: {
possibleFilters() {
return this.products
.map(({ topic }) => topic)
.filter((value, index, self) => self.indexOf(value) === index);
},
matchedProducts() {
return this.filters.length
? this.products.filter(product => this.filters.some(filter => product.topic.match(filter)))
: this.products
},
matchedAndSortedProducts() {
return this.matchedProducts.sort(/* something here */);
}
}
})