Vue JS 基于复选框数组过滤结果
Posted
技术标签:
【中文标题】Vue JS 基于复选框数组过滤结果【英文标题】:Vue JS filter results based on checkbox array 【发布时间】:2019-03-01 10:11:28 【问题描述】:我已经构建了一个 Vue JS 搜索组件来搜索和过滤属性网站的属性列表。搜索组件列在每个页面上,因此对我来说,使用 URL 搜索查询将我带到主属性页面然后使用类似 this.$route.query.search
的内容从我的查询中获取值并存储在变量中是有意义的。
属性数据来自一个 JSON 文件,基本上如下所示:
"data": [
"id": 12,
"sold": false,
"isFeatured": true,
"slug": "green-park-talbot-green-cf72-8rb",
"address": "Green Park, Talbot Green CF72 8RB",
"county": "Rhondda Cynon Taf",
"price": "695000",
"features": ["Modern fitted kitchen", "Integrated appliances", "Front and rear gardens"],
"type": "Semi-Detached",
"bedrooms": "3"
我的搜索查询是这样的:
/properties/?search=Address%20Here&type=Apartment&bedrooms=2&county=Maesteg
然后会过滤每一件事。
它的工作原理非常简单,在我的数据对象中,我有我的变量,它们获取每个查询并将它们存储如下:
data ()
return
searchAddress: this.$route.query.search,
searchType: this.$route.query.type,
searchBedrooms: this.$route.query.bedrooms,
searchCounty: this.$route.query.county
然后我在计算区域内有一个名为 filteredProperties 的过滤器,它过滤掉v-for
内的属性,这里不需要显示:
computed:
filteredProperties: function()
return this.properties.filter((property) =>
return property.address.match(this.searchAddress) && property.type.match(this.searchType) && property.bedrooms.match(this.searchBedrooms) && property.county.match(this.searchCounty)
);
现在这完全可以正常工作...但是我现在需要将其修改为而不是使用<select>
下拉列表,这是您当前选择卧室数量的方式,或者属性类型等,我现在需要用复选框替换属性类型 <select>
下拉列表,以便用户可以选择多个属性类型并将其作为数组添加到 URL 中。
我不太确定如何修改我的过滤器的这一部分,以便能够查找多种属性类型:
property.type.match(this.searchType)
非常感谢
更新
我最近尝试使用以下内容更新我的计算过滤器:
computed:
filteredProperties: function()
return this.properties.filter((property) =>
return property.address.match(this.searchAddress) &&
this.searchAddress.some(function(val)
return property.search.match(val)
) &&
property.type.match(this.searchType) &&
this.searchType.some(function(val)
return property.type.match(val)
) &&
property.bedrooms.match(this.searchBedrooms) &&
this.searchBedrooms.some(function(val)
return property.bedrooms.match(val)
) &&
property.county.match(this.searchCounty) &&
this.searchCounty.some(function(val)
return property.county.match(val)
)
);
我需要使用和不使用 URL 查询的搜索。
还尝试了 if/else 语句:
computed:
filteredProperties: function()
return this.properties.filter((property) =>
return property.address.match(this.searchAddress) &&
if (this.searchType.length > 1)
this.searchType.some(function(val)
return property.type.match(val)
)
else
property.type.match(this.searchType)
&&
property.bedrooms.match(this.searchBedrooms) &&
property.county.match(this.searchCounty)
);
更新
我通过执行以下操作使其正常工作:
computed:
filteredProperties: function()
return this.properties.filter((property) =>
let searchTypeMatch;
if (typeof this.searchType === "object")
searchTypeMatch = this.searchType.some(function(val)
return property.type.match(val)
)
else
searchTypeMatch = property.type.match(this.searchType)
return property.address.match(this.searchAddress) &&
searchTypeMatch &&
property.bedrooms.match(this.searchBedrooms) &&
property.county.match(this.searchCounty)
);
【问题讨论】:
您好,只是好奇您为什么使用match(...)
来查看给定地址是否包含在您的数据集中?此外,在您将其更改为复选框后,您可以保证您将在查询参数中获得一个数组。如果是,那么使用 Array.prototype 的.some(...)
进行修改将非常精简。
我可以将那个特定的.match()
更改为.some()
吗?还有哪些其他选择?
【参考方案1】:
我没有在 Vue 应用程序中使用过路由,但要使以下工作正常运行,您必须确保 this.$route.query.search
(和其他路由属性)是 []
(s)。
return this.searchAddress.some(function(val)
return property.address.match(val)
) &&
this.searchType.some(function(val)
return property.type.match(val)
) && ...
让我知道这是否适合您。
重新编辑:
您好,请将计算属性更改为以下
computed:
filteredProperties: function ()
let self = this
let routeConstraints = ['search', 'type', 'bedrooms', 'county'].filter(function (val)
return self.$route.query[val] !== undefined
)
if (routeConstraints.length === 0)
return self.properties
else
return routeConstraints.reduce(function (acc, val)
return acc.filter(function (property)
//basically I am checking if there is some value in the query parameter that matches properties.
if (self.$route.query[val] !== undefined)
//check if the route parameter is an array (object)
if (typeof this.searchType === "object")
self.$route.query[val] = [self.$route.query[val]]
return self.$route.query[val].some(function (item)
//changed the matching condition to indexOf
return property[val].match(item).length > 0
)
)
, self.properties)
基本上,
-
我正在尝试检查您的复选框选择中设置了哪些路线值
使用它来过滤属性数组。
如果没有设置,则返回所有属性。
希望这可行。
【讨论】:
我觉得这行不通,我试试.some()
这使用.some(..)
。请问为什么这行不通?
如果我将property.type.match(this.searchType)
更改为property.type.some(this.searchType)
,它不起作用。我也尝试使用你的代码,这也不起作用:/
嗨,感谢您的检查。请打印Array. isArray( this.searchType)
并检查是否是true
和typeof this.searchType
。谢谢。
好的,更新...我现在可以使用它了,它返回 true 并进行了一些修改,但是,如果数组中只有一项(例如:一种属性类型) 而不是倍数,它给了我一个错误:_this.searchType.some is not a function
但与多个一起工作正常吗?【参考方案2】:
您必须使用 JSON 作为查询参数才能序列化/反序列化数组。
data ()
return
searchAddress: this.$route.query.search ? JSON.parse(this.$route.query.search) : [],
searchType: this.$route.query.type ? JSON.parse(this.$route.query.type) : [],
searchBedrooms: this.$route.query.bedrooms ? JSON.parse(this.$route.query.bedrooms) : [],
searchCounty: this.$route.query.county ? JSON.parse(this.$route.query.county) : []
computed:
filteredProperties: function()
return this.properties.filter((property) =>
return (this.searchAddress.length ? this.searchAddress.some((address) =>
return property.address.match(address);
) : true) && (this.searchType.length ? this.searchType.some((type) =>
return property.type.match(type);
) : true) && (this.searchBedrooms.length ? this.searchBedrooms.some((bedrooms) =>
return property.bedrooms.match(bedrooms);
) : true) && (this.searchCounty.length ? this.searchCounty.some((county) =>
return property.county.match(county);
) : true)
);
然后你像这样发送查询参数
this.$router.push("/search?search=" + JSON.stringify(searchArray)
+ "&type=" + JSON.stringify(typeArray)
+ "&bedrooms=" + JSON.stringify(bedroomsArray)
+ "&county=" + JSON.stringify(countyArray)
);
【讨论】:
我刚试过这个,我得到:Unexpected token S in JSON at position 0
尝试搜索时
可能 JSON.parse() 的参数不是由 JSON.stringify() 生成的 - 你必须先序列化你的数组,然后才能反序列化它们。
this.$router.push("/search?search="+JSON.stringify(searchArray)+"&type="+JSON.stringify(typeArray)+"&bedrooms="+JSON.stringify(bedroomsArray)+"&county="+JSON.stringify(countyArray));
这听起来很酷,但它是一个通用的<form>
元素,带有一个指向/properties
的操作按钮,这是我的页面,而不是/search
。此外,看起来我必须将该代码绑定到点击事件中?那么如果他们只是按回车呢?我正在使用获取请求。
是/search
还是/properties
无关紧要。您应该绑定到表单本身上的submit
事件(它将捕获 Enter) - 然后准备正确的 URL,将 form.action
设置为此 URL,然后将 return true
以上是关于Vue JS 基于复选框数组过滤结果的主要内容,如果未能解决你的问题,请参考以下文章