Programing

Vue 계산된 속성이 데이터 개체 변경

c10106 2022. 3. 20. 12:31
반응형

Vue 계산된 속성이 데이터 개체 변경

기본적으로 내 데이터에 대해 다음과 같은 구조를 가지고 있다(이.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'
            ]
        }
    ]
}

그리고 나서 나는 계산된 결과를 출력해서 사람들이 태그로 이 .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
        }
    }
},

filterTerms()는 일치하는 게시물만 포함하는 카테고리를 반환한다.그래서 "앵그리"를 검색하면 "후고 위빙"만 나열되어 "제2 카테고리"만 반환된다.

문제는 계산된 함수를 실행하면 해당 함수의 복사본(단어)에만 있는 것이 아니라 이.단어의 두 번째 범주가 변경된다는 점이다.그것은 더 이상 스네이크 플리스킨을 포함하지 않는다.update_term.posts = update_posts로 범위를 좁혔다.그 선은 또한 이.단어를 바꾸는 것 같다.내가 할 수 있는 유일한 것은 전체 데이터 객체를 리셋하고 다시 시작하는 것이다.이것은 이상적이지 않다. 왜냐하면 그것은 항상 물건을 싣기 때문이다.처음에 이.terms를 로드해야 하고, 다른 사람이 검색 크라이테라를 지운 후 다시 사용할 수 있도록 변경되지 않은 상태로 있어야 한다.

나는 필터의 lodash 버전을 사용해 본 적이 있고 (그것이 변화를 줄 것이라고는 예상하지 못했지만) 포함시켰다.필터 대신 루프와 .push()를 더 복잡한 방법으로 사용해 보았다.

제가 무엇을 빠뜨리고 있나요?시간을 내어 봐줘서 고마워.

개체를 참조하지 않도록 복제하십시오. 다음과 같은 작업을 수행하십시오.

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

let terms = this.properties;

이것은 배열을 복사하는 것이 아니라 단지 다음에 대한 참조를 가지고 있을 뿐이다.this.terms. 이유는 JS 객체 및 배열은 참조형이기 때문이다.이것은 도움이 되는 동영상이다: https://www.youtube.com/watch?v=9ooYYRLdg_g

어쨌든, 다음 방법으로 어레이를 복사하십시오.this.terms.slice(). 물건이라면 쓸 수 있다.{...this.terms}.

내 컴퓨팅 기능을 다음과 같이 업데이트했다.

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

그리고 다른 곳에서 사용할 수 있도록 (이.copyObj()를 만들었다.다음과 같이 보인다.

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

참조URL: https://stackoverflow.com/questions/57224865/vue-computed-property-changes-the-data-object

반응형