【问题标题】:Vue based array filtering基于 Vue 的数组过滤
【发布时间】:2020-03-11 15:53:36
【问题描述】:

我创建了一个演示网站来向客户销售产品。该网站使用过滤器/搜索/排序等来轻松浏览不同的产品。我遇到的问题与过滤和搜索有关。我想让我的过滤器能够处理搜索结果。我已经尝试使用复选框和 Vue 中的计算属性进行此操作。

HTML

<div id="app">
            <h5>Search</h5>
            <input type="text" v-model="search" placeholder="Search title.."/><br><br>
            <h5>Filter</h5>
            <li v-for="filter in possibleFilters" :key="filter">
                <label>
                    <input type="checkbox" @change="toggleFilter(filter)" :checked="filters.includes(filter)">

                <span >{{filter}}</span>
                </label>
            </li>          
            <div class="block" v-for="(product, index) in filteredSearch">
                        <hr>
                        <h3>{{product.name}}</h3>
                        <p>Price: £{{product.price}}</p>
                        <p>Location: {{product.location}}</p>
                        <hr>

</div>
</div>

JavaScript

new Vue({
   el: "#app",
   data: {
      filters: [],
      search: "",
      products: [{
            name: "milk",
            location: "London",
            price: 100
         },
         {
            name: "oranges",
            location: "Birmingham",
            price: 80
         },
         {
            name: "apples",
            location: "Edinburgh",
            price: 90
         },
         {
            name: "bananas",
            location: "Paris",
            price: 120
         },
         {
            name: "bread",
            location: "Paris",
            price: 110
         },
         {
            name: "water",
            location: "Oslo",
            price: 90
         },
         {
            name: "soda",
            location: "London",
            price: 90
         },
         {
            name: "tea",
            location: "Oslo",
            price: 120
         },
         {
            name: "bakedbeans",
            location: "Oslo",
            price: 140
         }
      ],
   },
   methods: {
      toggleFilter(newFilter) {
         this.filters = !this.filters.includes(newFilter) ?
            [...this.filters, newFilter] :
            this.filters.filter(f => f !== newFilter)
      }
   },
   computed: {
      possibleFilters() {
         return [...new Set(this.filteredSearch.map(x => x.location))]
      },

      filteredSearch() {
         return this.products.filter(p => {
            var searchProduct = p.name.toLowerCase().includes(this.search.toLowerCase());
            var filterProduct = this.filters.length == 0 || this.filters.includes(p.location);

            return searchProduct && filterProduct
         })
      }
   },
})

问题是我不能多次选择过滤器。过滤器基于位置,我的目标是能够多次应用过滤器。目前我一次只能选择一个过滤器。

即如果我搜索“l”,它会返回牛奶和苹果,过滤器会显示伦敦和爱丁堡,我只能选择伦敦或爱丁堡,但不能同时选择两者。如果我选择伦敦,它应该只显示“牛奶”,同时仍然显示“爱丁堡”选项,当我选择两者时,它应该同时显示“牛奶”和“苹果”

显示问题的小提琴: https://jsfiddle.net/Calv7/L1vnqh63/9/

任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 你试过修改possibleFilters函数吗?据我所知,新过滤器来自那里。
  • 如何修改?我还在学习 Vue。

标签: javascript html vue.js


【解决方案1】:

这能解决您的问题吗?

possibleFilters() {
    return [...new Set(this.products.map(x => x.location))]
},

【讨论】:

  • 很好的答案:D
  • 我不希望过滤器对搜索结果起作用。这个例子可能会让人困惑我为什么需要它,但实际上我计划将它用作大型仓库中的库存管理,那里的位置可能是一些乱七八糟的 a1-b3-9a 等,有数千种产品。
  • @Calv,在这种情况下,您可以创建一个重置按钮,在单击时重置过滤器。
【解决方案2】:

这是一个基于您的小提琴的快速而肮脏的解决方案。只是为了让您了解如何分离两个过滤器。 在这里尝试解决方案https://jsfiddle.net/4839spkx/

 possibleFilters() {
    // we have some input, so show all location filters available in the filtered by input products
    if (this.search) {
        const filteredByInput = this.products.filter(p => p.name.includes(this.search.toLowerCase()))
        return [...new Set(filteredByInput.map(p => p.location))]
    }
    return [...new Set(this.filteredSearch.map(x => x.location))]
 },

【讨论】:

    【解决方案3】:

    由于您使用计算属性从过滤后的产品位置动态生成可能的过滤器,因此每次更新过滤后的产品时都会更新。我建议你创建一个新数组并用你的数据填充这个数组。

    HTML:

    ...
    <li v-for="filter in possibleFiltersArr" :key="filter">
        <label>
          <input type="checkbox" @change="toggleFilter(filter)" :checked="filters.includes(filter)">
    
          <span>{{filter}}</span>
        </label>
      </li>
    ...
    

    JS

    ...
     data: {
      posibleFiltersArr:[],
    ...
    created(){
            this.possibleFiltersArr=[...new Set(this.filteredSearch.map(x => x.location))]
        },
    ...
    

    你可以在created()方法中设置这个数组,你可以在搜索框输入一些文本后更新这个数组。

    【讨论】:

      猜你喜欢
      • 2019-03-01
      • 2019-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-08
      • 2015-09-13
      • 2017-09-08
      相关资源
      最近更新 更多