Вы можете использовать filter
в вычисляемом свойстве, чтобы возвращать только элементы, соответствующие поисковому запросу, с условным оператором, чтобы проверить, было ли что-либо введено в поле поиска, и, если нет, вернуть последние результаты поиска.
const data = {
"result": [{
product_name: 'mike',
business_name: 'student'
},
{
product_name: 'beckham john',
business_name: 'footballer'
},
{
product_name: 'walcott',
business_name: 'footballer'
},
{
product_name: 'cech',
business_name: 'footballer'
},
{
product_name: 'jordan',
business_name: 'actor'
},
{
product_name: 'tom',
business_name: 'actor'
},
{
product_name: 'john',
business_name: 'actor'
}
],
"recent": [{
product_name: 'mike',
business_name: 'student'
},
{
product_name: 'beckham john',
business_name: 'footballer'
},
{
product_name: 'walcott',
business_name: 'footballer'
}
]
}
new Vue({
el: '#app',
data() {
return {
filter: '',
items: null,
loading: false
}
},
computed: {
search() {
if (!this.items) {
return []
}
if (!this.filter) {
return this.items.recent
}
return this.items.result.filter(item => item.product_name.includes(this.filter) || item.business_name.includes(this.filter))
}
},
mounted() {
this.loading = true
this.fetchData().then(() => {
this.loading = false
})
},
methods: {
async fetchData() {
// here will simulate an ansynchronous call using fetch
//
// an actual fetch call will look something like the following:
//
// this.items = await fetch('/path/to/api').then(res => res.json()).then(json => json)
return new Promise((resolve, reject) => {
setTimeout(() => {
this.items = data
resolve()
}, 3000)
})
}
},
template: `
<div id="wrapper">
<label>Search</label>
<input v-model="filter">
<h4 v-if="loading" class="loading">Loading</h4>
<h4 v-else>{{ !!filter ? 'Search Results' : 'Recent Search' }}</h4>
<ul>
<li v-for="(item, index) in search" :key="index">
<p>Product Name: {{ item.product_name }}</p>
<p>Business Name: {{ item.business_name }}</p>
</li>
</ul>
</div>
`
})
#wrapper {
padding: 1rem 5rem;
display: flex;
flex-direction: column;
background-color: rgba(179,229,252,1);
}
.loading:after {
content: ' .';
animation: dots 1s steps(5, end) infinite;}
@keyframes dots {
0%, 20% {
color: rgba(0,0,0,0);
text-shadow:
.25em 0 0 rgba(0,0,0,0),
.5em 0 0 rgba(0,0,0,0);}
40% {
color: black;
text-shadow:
.25em 0 0 rgba(0,0,0,0),
.5em 0 0 rgba(0,0,0,0);}
60% {
text-shadow:
.25em 0 0 black,
.5em 0 0 rgba(0,0,0,0);}
80%, 100% {
text-shadow:
.25em 0 0 black,
.5em 0 0 white;}}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>