Filter list with Vue.js
Javascriptvue.jsJavascript Problem Overview
I just got started with Vue.js and here is what I'm doing: I am rendering a list of products, and each product has a name
, a gender
and a size
. I'd like users to be able to filter products by gender, by using an input to type the gender.
var vm = new Vue({
el: '#product_index',
data: {
gender: "",
products: [{name: "jean1", gender: "women", size: "S"}, {name: "jean2", gender: "men", size: "S"}]
},
methods:{
updateGender: function(event){
this.gender = $(event.target).val()
}
}
}
)
<div v-for="product in products" v-if="...">
<p>{{product.name}}<p>
</div>
<input v-on:change="updateGender">
I managed to get the gender updated, but I have an issue with the filtering part. When the page loads, I don't want any filtering. In the documentation, they advise to use v-if
but it doesn't seem compatible with this configuration.
If I use v-if
, I could do:
v-if="product.gender == gender"
But again, this doesn't work when the page load because gender is empty. I couldn't find a workaround for this.
How should I approach this issue ?
Javascript Solutions
Solution 1 - Javascript
Use computed properties - something like this (Example bellow filter items by type)
const app = new Vue({
el: '#app',
data: {
search: '',
items: [
{name: 'Stackoverflow', type: 'development'},
{name: 'Game of Thrones', type: 'serie'},
{name: 'Jon Snow', type: 'actor'}
]
},
computed: {
filteredItems() {
return this.items.filter(item => {
return item.type.toLowerCase().indexOf(this.search.toLowerCase()) > -1
})
}
}
})
Template:
<div id="app">
<div v-for="item in filteredItems" >
<p>{{item.name}}</p>
</div>
<input type="text" v-model="search">
</div>
Demo: http://jsbin.com/dezokiwowu/edit?html,js,console,output
Solution 2 - Javascript
You can try v-if="!gender || product.gender == gender"
Solution 3 - Javascript
Just modified @Nora's answer.
You need to change in the template as:
<div id="product_index">
<div v-for="product in products" v-if="!gender || product.gender===gender">
<p>{{product.name}}<p>
</div>
<input v-on:change="updateGender">
</div>
and in JS file as:
var vm = new Vue({
el: '#product_index',
data: {
gender: "",
products: [{name: "jean1", gender: "women", size: "S"}, {name: "jean2", gender: "men", size: "S"}]
},
methods:{
updateGender: function(event){
this.gender = event.target.value
}
}
}
);
Working Demo: https://jsbin.com/qocuraquki/edit?html,js,console,output
Solution 4 - Javascript
computed: {
filteredItems() {
return this.allStartupData.filter(item => {
let byName =
item.name.toLowerCase().indexOf(this.search.toLowerCase()) > -1;
let byDescription =
item.description.toLowerCase().indexOf(this.search.toLowerCase()) >
-1;
if (byName === true) {
return byName;
} else if (byDescription === true) {
return byDescription;
}
});
}
}
and then u can iterate through filteredItems like e.g
<v-flex v-for="(obj,index) in filteredItems" :key="index" xs12 md4>