I have a list of users from an array. And I want to filter them based on the search box(name) at the top. I saw that there are filters in VueJS 1. But not available in VuesJS 2. How can achieve this in VueJS 2
<input type="text" v-model="search"/>
<div class="row profile" v-for="customer in customers">
<div class="col-md-offset-1 col-md-3"><img :src="customer.profile_pic" class="profile-pic" /></div>
<div class="col-md-8"><h4 class="name">{{customer.name}}</h4></div>
</div>
<script>
data: function () {
return{
search: '',
customers: [
{ id: '1', name: 'user 1', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+91959657248', unread:'0' },
{ id: '2', name: 'user 2', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+919456664023', unread:'0' },
{ id: '3', name: 'user 3', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+919566565065', unread:'0' },
{ id: '4', name: 'user 4', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+916466004566', unread:'0' }
]
}
}
</script>
I like the answer by Nathan but I think this would work better and it eliminates the need for the var self = this
assignment. It will also keep eslint happy as the Vue eslint plugin frowns upon using indexOf
when looking for existence. Here it is:
data: function () {
return{
search: '',
customers: [
{ id: '1', name: 'user 1', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+91959657248', unread:'0' },
{ id: '2', name: 'user 2', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+919456664023', unread:'0' },
{ id: '3', name: 'user 3', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+919566565065', unread:'0' },
{ id: '4', name: 'user 4', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+916466004566', unread:'0' }
]
},
computed:
{
filteredCustomers () {
return this.customers.filter((customer) => {
return customer.name.toLowerCase().includes(this.search.toLowerCase())
})
}
}
I have done this by having my property "array" with the data elements and a computed property (array as well) with the filtered elements. The HTML renders the filtered elements. I have a property bound to the text box. For simplicity, something like this:
data: function () {
return{
search: '',
customers: [
{ id: '1', name: 'user 1', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+91959657248', unread:'0' },
{ id: '2', name: 'user 2', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+919456664023', unread:'0' },
{ id: '3', name: 'user 3', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+919566565065', unread:'0' },
{ id: '4', name: 'user 4', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+916466004566', unread:'0' }
]
},
computed:
{
filteredCustomers:function()
{
var self=this;
return this.customers.filter(function(cust){return cust.name.toLowerCase().indexOf(self.search.toLowerCase())>=0;});
}
}
Bind your HTML to filteredCustomers. You should now have a reactive HTML based on what you type on search. That "filter" method is native JavaScript for arrays, I lower-cased both values to make it case insensitive.
Here's a working example in fiddle: https://jsfiddle.net/dkmmhf5y/1/
Edit: Added fiddle and code corrections in computed property
Filters has been removed in vuejs 2. As suggested by @azamat-sharapov, you can have reusable filters using one of following 3 ways:
How can I do it in 2.0?
- Mixin
- Separate module with method
- Separate module with computed prop function
A simple implementation of filter in vuejs 2 can be using a computed property which can call a method to get filtered list. in the method you can pass list, query and it can return the filtered list. see following code and working demo here. Following are generic functions, which can be moved to mixin or module and can be re-used in multple components.
var vm = new Vue({
el: '#demo',
data: {
customers: [
{ id: '1', name: 'user 1', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+91959657248', unread:'0' },
{ id: '2', name: 'user 2', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+919456664023', unread:'0' },
{ id: '3', name: 'user 3', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+919566565065', unread:'0' },
{ id: '4', name: 'user 4', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+916466004566', unread:'0' }
],
columns: {
id : {
displayname : "id",
sortorder : 1
},
name : {
displayname : "name",
sortorder : 1
},
email : {
displayname : "email",
sortorder : 1
}
},
query: '',
},
computed: {
tableFilter: function () {
return this.findBy(this.customers, this.query, 'name')
}
},
methods: {
findBy: function (list, value, column) {
return list.filter(function (item) {
return item[column].includes(value)
})
}
}
})
This method worked good for me
computed: {
filteredList() {
return this.postList.filter(post => {
var vm = this;
return post.title.toLowerCase().includes(vm.search.toLowerCase())
})
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With