Vuejs Search filter
You can use the includes()
function of the array
to search any position in a sentence or phrase.
new Vue({ el: '#app', data() { return { searchQuery: null, resources:[ {title:"ABE Attendance",uri:"aaaa.com",category:"a",icon:null}, {title:"Accounting Services",uri:"aaaa.com",category:"a",icon:null}, {title:"Administration",uri:"aaaa.com",category:"a",icon:null}, {title:"Advanced Student Lookup",uri:"bbbb.com",category:"b",icon:null}, {title:"Art & Sciences",uri:"bbbb.com",category:"b",icon:null}, {title:"Auxiliares Services",uri:"bbbb.com",category:"b",icon:null}, {title:"Basic Skills",uri:"cccc.com",category:"c",icon:null}, {title:"Board of Trustees",uri:"dddd.com",category:"d",icon:null} ] }; }, computed: { resultQuery(){ if(this.searchQuery){ return this.resources.filter((item)=>{ return this.searchQuery.toLowerCase().split(' ').every(v => item.title.toLowerCase().includes(v)) }) }else{ return this.resources; } } } })
<!DOCTYPE html><html><head><meta name="viewport" content="width=device-width, initial-scale=1"><script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" ></head><body><div id="app"> <div class="panel panel-default"> <div class="panel-heading"> <strong> All Resources</strong></div> <div class="row"> <div class="search-wrapper panel-heading col-sm-12"> <input class="form-control" type="text" v-model="searchQuery" placeholder="Search" /> </div> </div> <div class="table-responsive"> <table v-if="resources.length" class="table"> <thead> <tr> <th>Resource</th> </tr> </thead> <tbody> <tr v-for="item in resultQuery"> <td><a v-bind:href="item.uri" target="_blank">{{item.title}}</a></td> </tr> </tbody> </table> </div> </div> </div></body></html>
Based on this answer → Vue.js search keyword in array
You could use computed
property for this case, so, i created one called filteredResources
which will be used in v-for
loop, i had used dummy data, but you could keep your resources
declared empty and call a promise function to fill it in created
hook, check this code if your are preferring single file component or the following code of you're using Vue via CDN
new Vue({ el: '#app', data() { return { searchQuery:'', resources:[ {title:"aaa",uri:"aaaa.com",category:"a",icon:null}, {title:"add",uri:"aaaa.com",category:"a",icon:null}, {title:"aff",uri:"aaaa.com",category:"a",icon:null}, {title:"bbb",uri:"bbbb.com",category:"b",icon:null}, {title:"bdd",uri:"bbbb.com",category:"b",icon:null}, {title:"bsb",uri:"bbbb.com",category:"b",icon:null}, {title:"ccc",uri:"cccc.com",category:"c",icon:null}, {title:"ddd",uri:"dddd.com",category:"d",icon:null} ] }; }, computed: { filteredResources (){ if(this.searchQuery){ return this.resources.filter((item)=>{ return item.title.startsWith(this.searchQuery); }) }else{ return this.resources; } } } })
<!DOCTYPE html><html><head><meta name="viewport" content="width=device-width, initial-scale=1"><script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" ></head><body><div id="app"> <div class="panel panel-default"> <div class="panel-heading" style="font-weight:bold"><span class="glyphicon glyphicon-align-justify"></span> All Resources</div> <div class="row"> <div class="search-wrapper panel-heading col-sm-12"> <input class="form-control" type="text" v-model="searchQuery" placeholder="Search" /> </div> </div> <div class="panel-body" style="max-height: 400px;overflow-y: scroll;"> <table v-if="resources.length" class="table"> <thead> <tr> <th>Resource</th> </tr> </thead> <tbody> <tr v-for="item in filteredResources"> <td><a v-bind:href="item.uri" target="_blank">{{item.title}}</a></td> </tr> </tbody> </table> </div> </div></div></body></html>
Here is Vue 3 version of a simple search.
const { createApp, ref } = Vueconst App = { setup() { let searchText = ref('') const list = [ 'orange', 'red', 'blue', 'black', 'white' ] function filteredList() { return list.filter(data => data.toLowerCase().includes(searchText.value.toLowerCase())) } return {searchText, filteredList} }}Vue.createApp(App).mount('#app')
<script src="https://unpkg.com/vue@next"></script><div id="app"> <input type="text" v-model="searchText"> <ul> <li v-for="data in filteredList()" :key="data"> {{ data }} </li> </ul></div>