【问题标题】:VueJS : Filter array of objects when user search for somethingVueJS:当用户搜索某些东西时过滤对象数组
【发布时间】:2023-04-09 00:17:01
【问题描述】:

基本上,此代码负责将sortedCars 数组中包含的汽车名称列表显示到下拉列表中。 (此数组按字符串 asc 排序)。

现在,我添加了一个输入文本,并尝试自动过滤与输入的名称值匹配的汽车列表。

使用以下代码,用户界面永远不会更新。哪里错了?

<template>
        <div class="btn-group pull-left">
            <input type="text" @keyup="onFilterCars" v-model="searchCarTextValue" />
            <a v-for="car in this.sortedCars" :key="car.name" @click="onSelectCategoryFilterLabel" class="dropdown-item" href="#">
                <span v-else>{{ car.name }}</span>
            </a>
        </div>
</template>

<script>
export default {
    data() {
        return {
            inputFilterText: "",
            mapFilteringEnabled: false,
            searchCarTextValue: ""
        };
    },
    props: {
        cars: {
            type: Array
        }
    },
    computed: {

        sortedCars: function() {

            function compare(a, b) {

                if (a.name < b.name)
                    return -1;
                if (a.name > b.name)
                    return 1;

                return 0;
            }

            var sortedArr = this.cars.sort(compare);

            return sortedArr;
        }

    },
    methods: {

        onFilterCars() {
            if (this.searchCarTextValue) {
                var arrayFiltered = this.sortedCars.filter( (car) => {
                    return car.name.toLowerCase().indexOf(this.searchCarTextValue.toLowerCase()) != -1
                });
                this.sortedCars = arrayFiltered;
            }
        }

    }
};
</script>

【问题讨论】:

  • 一个注释:this.sortedCars 每次都会改变,所以一段时间后它什么都不包含,相反,您应该将所有汽车的列表保存在其他地方并从该列表中过滤而不更改它,因此有效地有两个列出一辆包含所有汽车和一辆已过滤
  • computed 属性将在其依赖属性更改时automatically recompute。你根本不需要onFilterCars 处理程序。
  • 你有两次div"....不是答案而是问题
  • 和一个没有v-ifspan v-else

标签: javascript vue.js vuejs2


【解决方案1】:

在vue中很容易过滤,通常我采取这样的方法:

<template>
<div>
    <div" class="btn-group pull-left">
        <input type="text" v-model="filters.searchCarTextValue" />
    </div">
</div>
</template>

<script>
export default {
{
    data(){
        return {
            filters:{
                searchCarTextValue: ''
            }
        }
    },
    props: {
        cars: {
            type: Array
        }
    },
    computed: {
        // returns list of cars based of filters
        filtered_cars(){
            let vm = this;
            if(!vm.filters.searchCarTextValue){
                return [];
            }
            return vm.sortedCars.filter(car => {
                return car.name.toLowerCase().indexOf(vm.filters.searchCarTextValue.toLowerCase()) != -1
            })
        },
        sortedCars: function() {

            function compare(a, b) {

                if (a.name < b.name)
                    return -1;
                if (a.name > b.name)
                    return 1;

                return 0;
            }

            var sortedArr = this.cars.sort(compare);

            return sortedArr;
        }
    }
}
</script>

这种方式不需要使用过滤方法,因为每当filters.searchCarTextValuesortedCars 改变时,计算值都会改变。所以你也不需要一个按钮来触发过滤。

工作示例:https://jsfiddle.net/rmfbpLk9/2/

【讨论】:

    【解决方案2】:

    正如人们在 cmets 中所说,代码中有几个错误,我已经修复了所有这些错误,并将您的 method 更改为 computed,并删除了您实际设置变量和计算的所有位置声明错误。

    工作沙盒:https://codesandbox.io/s/musing-feather-10isg

    代码:

    <template>
      <div>
        <div class="btn-group pull-left">
          <input type="text" v-model="searchCarTextValue">
          <a
            v-for="car in this.filteredCars"
            :key="car.name"
            @click="onSelectCategoryFilterLabel"
            class="dropdown-item"
            href="#"
          >
            <span>{{ car.name }}</span>
          </a>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          inputFilterText: "",
          mapFilteringEnabled: false,
          searchCarTextValue: ""
        };
      },
      props: {
        cars: {
          type: Array
        }
      },
      computed: {
        filteredCars() {
          function compare(a, b) {
            if (a.name < b.name) return -1;
            if (a.name > b.name) return 1;
    
            return 0;
          }
    
          let cars = this.cars.filter(car => {
            return (
              car.name
                .toLowerCase()
                .indexOf(this.searchCarTextValue.toLowerCase()) != -1
            );
          });
    
          cars.sort(compare);
    
          return cars;
        }
      },
      methods: {
        onSelectCategoryFilterLabel() {
          console.log("OK");
        }
      }
    };
    </script>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-23
      • 1970-01-01
      • 2021-12-16
      • 2013-12-18
      • 2019-01-05
      • 2021-10-31
      • 2020-07-12
      • 1970-01-01
      相关资源
      最近更新 更多