javascript - 搜索和过滤功能仍然无法正常工作(Vue JS)
问题描述
我正在弄清楚我的搜索和过滤功能如何正常工作。stock
我创建了一个搜索功能并按、distance
、price
和过滤搜索结果time response
。我的搜索功能运行良好。但是,我制作的过滤器功能仍然不起作用。
我想要在我进行搜索之后,并想进一步过滤搜索,当下拉列表之一发生变化时,有股票和距离等选项,搜索结果项也会根据过滤器(例如:股票)是否可用而变化. 还有其他过滤器,例如价格和时间响应。当我点击价格时,商品将按照最低价格到最高价格进行排序。而当我点击时间响应时,搜索项会按照响应从快到晚的顺序排列。
示例案例
在Type
,我选择BMW
。然后我点击搜索按钮。将显示类型为 2 的项目结果BMW
。然后,在Distance
我选择的过滤器中500 KM
。它应该只显示 1 个结果。但过滤器不起作用。
如果有 6 个商品的结果,并且我单击price
该商品将从最低价格到最高价格排序
我已经制作了如下代码,有人可以帮我解决这个问题吗?
new Vue({
el: '#app',
data: {
selectedType: '',
selectedCountry: '',
selectedYear: '',
selectedStock:'',
selectedDistance:'',
items: [{
name: 'Carthy',
type: 'mercedes',
year: '2020',
country: 'england',
stock: 'available',
distance: '500',
price: '1900',
response: 'fast'
},
{
name: 'Holand',
type: 'mercedes',
year: '2020',
country: 'england',
stock: 'available',
distance: '500',
price: '1050',
response: 'fast'
},
{
name: 'Nolan',
type: 'mercedes',
year: '2020',
country: 'england',
stock: 'available',
distance: '500',
price: '1000',
response: 'fast'
},
{
name: 'Edgar',
type: 'bmw',
year: '2020',
country: 'belgium',
stock: 'available',
distance: '5000',
price: '1200',
response: 'fast'
},
{
name: 'John',
type: 'bmw',
year: '2019',
country: 'england',
stock: 'available',
distance: '500',
price: '1500',
response: 'fast'
},
{
name: 'Axel',
type: 'mercedes',
year: '2020',
country: 'england',
stock: 'sold',
distance: '500',
price: '1600',
response: 'late'
}
],
searchResult: [],
itemsToShow: 2,
totalItems: 0,
sortByPrice: true,
sort: 'price',
sortByTime: true,
sort: 'time'
},
computed:{
filterItem: function() {
let filterStock = this.selectedStock,
filterDistance = this.selectedDistance
return this.searchResult.filter(function(item) {
let filtered = true
if (filterStock && filterStock.length > 0) {
filtered = item.stock == filterStock
}
if (filtered) {
if (filterDistance && filterDistance.length > 0) {
filtered = item.distance == filterDistance
}
}
return filtered
})
}
},
methods: {
search: function() {
let filterType = this.selectedType,
filterCountry = this.selectedCountry,
filterYear = this.selectedYear
this.itemsToShow = 2;
this.searchResult = this.items.filter(function(item) {
let filtered = true
if (filterType && filterType.length > 0) {
filtered = item.type == filterType
}
if (filtered) {
if (filterCountry && filterCountry.length > 0) {
filtered = item.country == filterCountry
}
}
if (filtered) {
if (filterYear && filterYear.length > 0) {
filtered = item.year == filterYear
}
}
return filtered
})
},
priceSort: function(){
this.sortByPrice = !this.sortByPrice
if(this.sortByPrice)
this.sort = 'price'
},
timeSort: function(){
this.sortByTime = !this.sortByTime
if(this.sortByTime)
this.sort = 'time'
}
},
mounted() {
this.search()
}
})
.list-item{
margin-top:50px;
}
#app{
position:relative;
padding-bottom: 200px;
}
span{
margin: 0 15px;
cursor:pointer;
}
.filter-box{
margin-top:15px;
}
.card{
box-shadow:0px 10px 16px rgba(0,0,0,0.16);
width:400px;
padding:20px 30px;
margin-bottom:30px;
}
button{
background-color: #1cf478;
border:none;
padding: 10px 25px;
font-weight:bold;
border-radius: 15px;
}
select{
border:none;
padding: 10px 15px;
background-color:#c1c1c1;
border-radius:10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.1/vue.js"></script>
<div id="app">
<div class="search-box">
<select v-model="selectedType">
<option value="" disabled selected hidden>Type</option>
<option value="mercedes">Mercedes</option>
<option value="bmw">BMW</option>
</select>
<select v-model="selectedCountry">
<option value="" disabled selected hidden>Country</option>
<option value="belgium">Belgium</option>
<option value="england">England</option>
</select>
<select v-model="selectedYear">
<option value="" disabled selected hidden>Year</option>
<option value="2019">2019</option>
<option value="2020">2020</option>
</select>
<button @click="search">Search</button>
</div>
<div class="filter-box">
<h6>Filter:</h6>
<select v-model="selectedStock" @change="filterItem">
<option value="" disabled selected hidden>Stock</option>
<option value="sold">Sold</option>
<option value="available">Available</option>
</select>
<select v-model="selectedDistance" @change="filterItem">
<option value="" disabled selected hidden>Kilometers</option>
<option value="500">500 KM</option>
<option value="5000">5000 KM</option>
<option value="10000">10.000 KM</option>
</select>
<span class="price" @click="priceSort">Price</span>
<span class="response" @click="timeSort">Time Response</span>
</div>
<section class="result">
<div class="container-fluid">
<div class="row list-item" v-for="(item, id) in searchResult" :key="id">
<div class="col-3 card" v-if="id < itemsToShow">
<p>Name: {{ item.name }}</p>
<p>Car: {{ item.type }}</p>
<p>Year: {{ item.year }}</p>
<p>Country: {{ item.country }}</p>
<p>Price: ${{ item.price }}</p>
<p>stock: {{ item.stock }}</p>
<p>distance: {{ item.distance }}</p>
</div>
</div>
<div class="row">
<div class="col-12">
<button @click="itemsToShow += 1">Load More</button>
</div>
</div>
</div>
</section>
</div>
解决方案
请参阅此代码框以获取基于您的代码的工作演示。
我的改变
- 添加
filterResult
在处理过滤结果data
的顶部searchResult
,我们只渲染filterResult
为结果。这将分离“搜索”和“过滤”的逻辑,逻辑更清晰。 - 每当过滤器选择的值发生变化时,我们都会触发
filterItems
方法作为@click
处理程序。(以前您使用的是计算属性,这不够简单,我们可以简单地调用一个方法来@change
更新filter results
数据。 - 每当触发搜索时,我们都会重置过滤器选择值,并显示所有搜索结果(
filterResult
与searchResult
没有过滤器值相同)。 - 至于排序,对于这两个排序
span
元素,我们只能更新this.sort
数据,只要排序条件发生变化,就使用watch
to triggersortItems
方法,这样会更简单一些。您可能需要根据需要调整sortItems
方法。当然,您可以为这两个“排序”按钮编写两个单独的方法,这完全取决于您:)
推荐阅读
- android - 无法从 RxJava2 链触发 Android Activity [Android][RxJava]
- angular - 具有拖放功能的角垫树
- python - Django过滤通用表单通过用户名从基于通用类的视图中选择属性或预填充并隐藏表单选择属性
- python - 尽管有多个套接字,但所有接口均未使用
- javascript - 当将 redux 状态映射到 props 到组件中时,它返回 undefined
- windows - 键盘快捷键或 PowerShell 命令打开设置重复键和慢键
- javascript - List.js 未排序
- flutter - 如何设置录制视频的限制,如 snapchat
- asp.net-core-2.0 - API Json 响应大小限制
- sql - 在 SQL Server 中将 CTE 转换为临时表以获取所有可能的父级