【问题标题】:Vue filtering objects propertyVue过滤对象属性
【发布时间】:2023-04-09 10:46:01
【问题描述】:

我有一个这样的对象数组(大陆):

data() {
    return {
        continents: [
            {
                name: "South America",
                countries: [
                    {
                        name: "Paraguay"
                    },
                    {
                        name: "Chile"
                    }
                ]
            },
            {
                name: "North America",
                countries: [
                    {
                        name: "Costa Rica"
                    },
                    {
                        name: "Mexico"
                    }
                ]
            }
        ]
    }
}


// 6 continents and over 250 countries within.

我试图像这样用v-model 'filter' 过滤它

computed: {
    filtered() {
        return this.continents.filter(continent => {
            continent.countries = continent.countries.filter(country => {
                return country.name.match(new RegExp(this.filter, 'i'));
            });
            return continent.countries.length;
        });
    }
}

并使用v-for 指令渲染它,如下所示:

<input v-model="filter" type="text">
<div v-for="continent in filtered" v-if="filtered.length" class="countries-group">
    <h4>{{ continent.name }}</h4>
    <ul class="country-list">
        <li v-for="country in continent.countries" class="country-item">{{ country.name }}</li>
    </ul>
</div>

它几乎可以工作,但是我的计算属性过滤修改了原始国家数据,所以当我尝试退格过滤器v-model 时,它不会返回初始化数据,因为它已经被过滤对象覆盖。

【问题讨论】:

    标签: javascript arrays vue.js


    【解决方案1】:

    我的计算属性过滤修改了原始国家数据

    你不应该这样做。不要修改计算属性中的状态,因为它可能会触发重新评估其他计算属性并导致令人困惑的错误。计算属性是指以某种方式转换(不改变)组件状态的纯函数。

    试试这个:

    filtered() {
      const filter = this.filter.toLowerCase();
    
      return this.continents
        .map(continent => Object.assign({}, continent, {
          countries: continent.countries.filter(country => {
            return country.name.toLowerCase().includes(filter);
          }),
        })
        .filter(continent => continent.countries.length);
    }
    

    【讨论】:

    • 哦,谢谢。那行得通。但我们应该交换过滤器和地图调用,我猜
    • 不会有任何区别。在执行 map() 之前先减小数组的大小 (filter()) 会获得更好的性能。
    • 但这让我们可以避免用空国家渲染大陆
    猜你喜欢
    • 2017-09-22
    • 1970-01-01
    • 1970-01-01
    • 2013-11-19
    • 1970-01-01
    • 2018-12-25
    • 2018-04-07
    • 2015-04-25
    • 2010-09-25
    相关资源
    最近更新 更多