Search app with Lunr
by Jay Angelo Valmocina
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.22/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lunr.js/2.3.5/lunr.min.js"></script>
<div id="app">
<mysearchbtn inline-template :search.sync="search">
<div>
<input type="text" placeholder="type to search" v-model="search" @input="$emit('update:search', $event.target.value)" />
</div>
</mysearchbtn>
<p>Number of results: <b>{{list.length}}</b></p>
<mylist inline-template :list="list">
<ul>
<li v-for="item in list" :key="item.id">{{item.name}}</li>
</ul>
</mylist>
</div>
CSS
* {
font-family: Helvetica;
}
input {
border: none;
padding: 14px;
font-size: 16px;
box-shadow: 0px 2px 2px lightgrey;
}
ul li {
font-size: 15px;
list-style-type: none;
padding: 15px;
margin-bottom: 10px;
box-shadow: 0px 2px 2px lightgrey;
}
JavaScript
Vue.component('mysearchbtn', {
props: ['search']
})
Vue.component('mylist', {
props: ['list']
})
new Vue({
el: '#app',
data() {
return {
original: [],
list: [],
search: '',
resuls: [],
searchIndex: null
}
},
mounted() {
axios('https://jsonplaceholder.typicode.com/comments')
.then(data => {
this.original = data.data
this.list = this.original
this.buildIndex()
})
this.$watch('search', () => {
this.resuls = this.searchIndex.search(this.search)
this.list = []
this.resuls.forEach(d => {
this.original.forEach(p => {
if (d.ref == p.id) this.list.push(p)
})
})
})
},
methods: {
buildIndex() {
var documents = this.original
this.searchIndex = lunr(function() {
this.ref('id')
this.field('name')
this.field('body')
this.field('email')
documents.forEach(doc => {
this.add(doc)
})
})
}
}
})