我是使用vue js创建搜索过滤器的,我当前的问题是,我想在创建页面时显示recentSearch
历史记录中的数据,而不是显示recentSearch
中的所有json数据,然后当我开始输入,它将从searchProduct
我的searchProduct.php
的json格式
{"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' }
]}
HTML示例
<div id="SearchVueContenPage">
<input type="search" v-model="q" name="q"/>
<ul>
<li v-for="row in filterSearchs" >{{row.product_name}}</li>
</ul>
</div>
这是我的JavaScript
const appSearch = new Vue({
el: "#SearchVueContenPage",
data() {
return {
searchProduct: [], /*show this item only for search*/
recentSearch: [], /*show this when page load or not searching*/
q: ''
}
},
methods: {
},
created() {
fetch(ajax_appserver("public", "_api/searchProduct.php?fetch_api=true&getFromApp=vue&search="))
.then(response => response.json())
.then(json => {
this.searchProduct = json.result;
this.recentSearch = json.recent.slice(0, 3);
});
},
computed: {
filterSearchs: function(){
return this.searchProduct.filter((row) => {
var query = this.q.toLowerCase();
return row.product_name.toLowerCase().indexOf(query)>-1 || row.business_name.toLowerCase().indexOf(query)>-1;
});
}
}
});
答案 0 :(得分:0)
您可以在计算属性中使用filter
,以仅返回与搜索查询匹配的项目和条件语句,以测试是否在搜索框中输入了任何内容,如果没有,则返回最近的搜索结果。 / p>
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>