【问题标题】:Vue computed property changes the data objectVue计算属性改变数据对象
【发布时间】:2019-12-05 02:00:19
【问题描述】:

我的数据基本上有这个结构(this.terms):

{
    name: 'First Category',
    posts: [
        {
            name: 'Jim James',
            tags: [
                'nice', 'friendly'
            ]
        },
        {
            name: 'Bob Ross',
            tags: [
                'nice', 'talkative'
            ]
        }
    ]
},
{
    name: 'Second Category',
    posts: [
        {
            name: 'Snake Pliskin',
            tags: [
                'mean', 'hungry'
            ] 
        },
        {
            name: 'Hugo Weaving',
            tags: [
                'mean', 'angry'
            ]
        }
    ]
}

然后我输出计算结果,以便人们可以按标签过滤 this.terms。

computed: {
    filteredTerms: function() {
        let self = this;
        let terms = this.terms; // copy original data to new var

        if(this.search.tags) {
            return terms.filter((term) => {
                let updated_term = {}; // copy term to new empty object: This doesn't actually help or fix the problem, but I left it here to show what I've tried.
                updated_term = term;

                let updated_posts = term.posts.filter((post) => {
                    if (post.tags.includes(self.search.tags)) {
                        return post;
                    }
                });

                if (updated_posts.length) {
                    updated_term.posts = updated_posts; // now this.terms is changed even though I'm filtering a copy of it
                    return updated_term;
                }
            });
        } else {
            return this.terms; // should return the original, unmanipulated data
        }
    }
},

filteredTerms() 返回仅包含匹配帖子的类别。因此,搜索“angry”只会返回“Second Category”,并仅列出“Hugo Weaving”。

问题是,运行计算函数会更改 this.terms 中的 Second Category 而不仅仅是该函数中的副本(terms)。它不再包含 Snake Pliskin。我已将其范围缩小到 updated_term.posts = updated_posts。那条线似乎也改变了this.terms。我唯一能做的就是重置整个数据对象并重新开始。这不太理想,因为它会一直在加载东西。我需要 this.terms 最初加载,并且保持不变,以便在有人清除他们的搜索条件后恢复到它。

我尝试过使用过滤器和包含的 lodash 版本(尽管我并没有真正期望这会有所作为)。我尝试使用更复杂的方式来使用 for 循环和 .push() 而不是过滤器。

我错过了什么?感谢您抽出宝贵时间查看此内容。

【问题讨论】:

    标签: javascript vue.js vuejs2 vue-component


    【解决方案1】:

    尝试克隆对象而不是引用它,你应该这样做:

       let terms = [];
       Object.assign(terms,this.terms);
    

    【讨论】:

    • 谢谢!让我走上正确的道路!实际上,我必须遍历术语数组并在术语对象上运行 Object.assign,但它正确地克隆了我的原始数据。
    【解决方案2】:

    让条款 = this.terms;

    这不会复制数组,它只是保存对this.terms 的引用。原因是因为 JS 对象和数组都是引用类型。这是一个有用的视频:https://www.youtube.com/watch?v=9ooYYRLdg_g

    无论如何,使用this.terms.slice() 复制数组。如果是对象,可以使用{...this.terms}

    【讨论】:

    • 很棒的视频!谢谢回复。我今天学到了一些新东西。
    【解决方案3】:

    我用这个更新了我的计算函数:

    let terms = [];
    for (let i = 0; i < this.terms.length; i++) {
        const term = this.copyObj(this.terms[i]);
        terms.push(term);
    }
    

    并创建了一个方法 (this.copyObj()),以便我可以在其他地方使用它。它看起来像这样:

    copyObj: function (src) {
        return Object.assign({}, src);
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-16
      • 2018-02-20
      • 2022-01-04
      • 2018-01-22
      • 2019-05-25
      • 2017-11-01
      • 1970-01-01
      • 2020-02-03
      • 2021-10-15
      相关资源
      最近更新 更多