基于复选框数组的Vue JS过滤器结果

时间:2018-09-25 17:47:52

标签: javascript arrays json vue.js nuxt.js

我已经构建了一个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中。 / p>

我不太确定如何修改过滤器的这一部分以查找多种属性类型:

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)
      });
    }
  }

2 个答案:

答案 0 :(得分: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)
);

答案 1 :(得分:1)

我还没有在Vue应用程序中使用路由,但是要使以下工作正常进行,您必须确保this.$route.query.search(是)[](一个)。

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)
        }
    }
}

基本上,

  1. 我正在尝试从您的复选框中检查设置的路由值
  2. 使用它来过滤属性数组。
  3. 如果未设置任何属性,则返回所有属性。

希望这行得通。

相关问题