Vue 过滤对象属性 [英] Vue filtering objects property

查看:76
本文介绍了Vue 过滤对象属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

data() {返回 {大陆:[{名称:南美洲",国家: [{名称:巴拉圭"},{名称:智利"}]},{名称:北美",国家: [{名称:哥斯达黎加"},{名称:墨西哥"}]}]}}//6 大洲和 250 多个国家.

我试图用 v-model 'filter' 来过滤它

计算:{过滤(){返回 this.continents.filter(大陆 => {大陆.国家=大陆.国家.过滤器(国家=> {返回 country.name.match(new RegExp(this.filter, 'i'));});返回 continent.countries.length;});}}

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

<div v-for="已过滤的大陆" 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>

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

解决方案

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

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

试试这个:

filtered() {const filter = this.filter.toLowerCase();返回 this.continents.map(大洲=> Object.assign({}, 大洲, {国家: 大陆.国家.过滤器(国家=> {返回 country.name.toLowerCase().includes(filter);}),}).filter(大陆 => 大陆.国家.长度);}

I have an array of objects like this (continents):

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.

And Im trying to filter it with v-model 'filter' like this

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

And render it with v-for directive like this:

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

And it almost works, but my computed property filtered modifies the original countries data, so when i'm trying to backspace filter v-model, it not return the inited data because its already overriding with filtered objects.

解决方案

my computed property filtered modifies the original contries data

You shouldn't do this. Don't modify state within computed properties because it may trigger other computed properties to be re-evaluated and cause confusing bugs. Computed properties are meant to be pure functions which transforms (without mutating) the component's state in some way.

Try this:

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

这篇关于Vue 过滤对象属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆