본문 바로가기

트러블슈팅

값을 변경했는 데 computed 내 관련 메소드가 동작하지 않을 때, Vue.set을 사용하자

문제

Kendo라는 UI 프로그램과 Vue를 이용해 화면 기능을 구현하는 프로젝트였다.

아래와 같이 Conent를 선택해서, Add 버튼을 누르면 아래 Grid로 이동해야 된다.

 

selected된 항목들을 바로 계산할 수 있도록 아래와 같이 computed를 사용했다.

allContentGridData는 상위 Grid에 노출되는 Data이다.

computed: {
    selectedDataItems () {
      return this.allContentGridData.filter(item => item.selected === true)
    }
}

 

checkbox를 클릭할 때마다 selectedDateItems가 실행될 거라 생각하고, checkBox 선택 시 onSelectionChange 메소드가 실행되도록 하였다. selected = true 값은 false로 false는 true로 변경하는 메소드다.

methods: {
    onSelectionChange (event) {
      event.dataItem[this.selectedField] = !event.dataItem[this.selectedField]
    }
}

 

 

Add 버튼을 클릭하면 computed에 있는 selectedDataItems를 이용해 선택된 항목들만 아래 Grid로 보내준다.

method: {
    clickAddButton: function () {
      const selectedContents = this.selectedDataItems
      this.excludeContent({
        gridName: 'allContent',
        contents: selectedContents
      })
      this.includeContent({
        gridName: 'documentContent',
        contents: selectedContents
      })
    }
}

 

그런데, checkbox를 선택했음에도 clickAddButton이 실행될 때, this.selectedDataItems 결과가 빈 배열로 나왔다.

 

원인

console을 찍어보니 체크 박스 선택 시 onSelectionChange가 실행되고 나서, computed의 selectedDateItems가 실행되지 않고 있었다. 원인을 찾아보니, Vue에서는 Object나 Array의 내부항목이 변경될 경우 감지가 되지 않는다.

 

selectedDateItems는 배열의 값을 직접 변경해주고 있었고, 이는 Vue의 반응성 시스템에서는 감지되지 않았던 것이다.

event.dataItem[this.selectedField] = !event.dataItem[this.selectedField]

 

 

Vue.set(object, key, value) 메소드를 사용하면 변경이 감지되지 않는 객체나 Array 내부 항목이더라도 반응성 속성을 추가 할 수 있다.

해결

Vue.set 메소드를 사용하여, 아래와 같이 변경해주었고, Vue가 변경을 감지하면서 selectedDateItems도 잘 실행되어 선택된 항목들을 가져올 수 있었다.

methods: {
    onSelectionChange (event) {
      let checked = event.event.target.checked
      Vue.set(event.target.dataItems[i], this.selectedField, checked)
    }
}

참고 자료

https://ftfuture.tistory.com/46

 

Vue에서 Data 변화가 감지되지(Reactive state)않는 경우

#. Vue에서 v-if나 v-model등으로 출력중인 데이터가 변할경우 새로 바뀐 값이 바로바로 적용되어 진다 하지만 적용이 안되는 경우가 있다. (https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats) - Vue C

ftfuture.tistory.com

https://beomy.tistory.com/66

 

[Vue.JS] 반응형 시스템

Vue의 가장 두드러지는 특징 중 하나는 눈에 띄지 않는 반응형 시스템입니다. 모델은 단순한 JavaScript 객체입니다. 모델이 수정되면 화면이 갱신됩니다. 이번 포스트에서 이러한 반응형 시스템을

beomy.tistory.com