[Vue.js]인턴과정의 지식.. - 1. 리스트렌더링

David Im·2022년 4월 9일
0

(해당글은 2020.12.18에 작성된 네이버 블로그가 원글입니다)

현재 정직원채용을 앞두고 인턴의 마지막 달을 보내고있다.
Java쪽은 워낙에 많이 다루어봤고 들어오자마자 진행한 프로젝트도 Android App 개발이었기
때문에 무난하게 흘렸지만.. JS는 HTML과 CSS 말고는 제대로 다루어 본적이 없다. 말이 다루어본거지 진짜 HTML을 끄적여서 작성하는 수준 ㅡㅡ..

그런 나에게 Vue라는 녀석은 굉장히 큰 숙제로 다가왔다. 물론 설명을 해주시긴 했지만 너무나도 최신기술이라...

확실히 다뤄보면 편하긴 편하다. 데이터가 실시간으로 적용되는것부터 해서 컴포넌트를 통해 그려지기 때문에 모듈화?가 잘 될 수 있다는 것 등등..

뭐.. 잡소리는 여기까지 거두절미하고 ..

문제는 아래와같았다.

  1. 게시판을 만들기 위해 답글 기능을 제작

  2. Vuetify의 V-Data-table을 이용하여 각 행에는 질문을 받고 해당 질문을 클릭시 Expand가 되어 답글을 달수있다.

  3. 누구나 아는 것이지만 답글은 각 Line마다 개별 적용이어야하며, 내용저장또한 개별 적용이어야한다.

3번에서 걸리게 되었는데 답글의 내용이 개별저장되는부분까지는 구현을 했지만 답글을 달기위해 Click이벤트를

발생시키면 모두 똑같이 동작하는것 하하...

찾고 찾다보니 리스트렌더링의 오류라더라..

Vue의 공식문서에도 나와있었는데 이해가 되질 않으니.. 활용을 못했던것일 뿐이었다.


주의 사항

JavaScript의 제한으로 인해 Vue는 배열에 대해 다음과 같은 변경 사항을 감지할 수 없습니다.

  1. 인덱스로 배열에 있는 항목을 직접 설정하는 경우, 예: vm.items[indexOfItem] = newValue

  2. 배열 길이를 수정하는 경우, 예: vm.items.length = newLength

예시:

var vm = new Vue({
  data: {
    items: ['a', 'b', 'c']
  }
})
vm.items[1] = 'x' // reactive하지 않음
vm.items.length = 2 // reactive하지 않음

한마디로 저렇게 직접적으로 값을 주거나 없는 값을 넣어주는것에 대해서는 reactive 하지 못하다는것. 제대로 반응을 못해 실시간으로 반영을 처리할수없는것이다.

처리할수있다 하더라도 다음에 값이 변경되는것은 반영을 해주지 못할 가능성이 크다.

내 소스코드를 보니 나도 아래와 같이 설정을 해놓았는데..

commitAnswer: function(item){
item.answer = this.tempAnswer
// tempAnswer는 answer의 값을 임시로 가지고있기 위한 곳
// item.answer는 v-model로 data-binding되어 실시간으로 답글의 변화를 감지하고 저장하는 곳
...
}

위와 같이 하면 직접적으로 item.answer라는 곳에 tempAnswer객체의 값을 설정을 해주는 것이기때문에 값이 consolelog로 찍을경우 출력은 되지만 홈페이지는 반영이 되지 않는다.

그래서 아래와 같이 사용해야한다.

commitAnswer: function(item){
this.$set(item,'answer',item.tempAnswer)
...

Vue 공식문서에 나와있는 리스트렌더링의 1번항목에 대한 수정을 $set 메서드를 이용하여 적용한것이다.

아래의 내용이 Vue 공식문서의 내용이다.

주의 사항 중 1번을 극복하기 위해 다음 두 경우 모두 vm.items[indexOfItem] = newValue 와 동일하게 수행하며, 반응형 시스템에서도 상태 변경을 트리거 합니다.

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)

You can also use the vm.$set instance method, which is an alias for the global Vue.set:

vm.$set(vm.items, indexOfItem, newValue)

(전역 Vue.set의 별칭인 vm.$set 메서드를 이용하여 지정할수도 있습니다.)


이렇게 바꿔서 적용했더니 매우 잘된다..

그래서 편집,작성 모드에 대한 부분도 아래처럼 옮겨서 바꿔 코딩했더니 매우 잘작동한다.

    commitAnswer: function(item){
      // item.answer = this.tempAnswer
      this.$set(item, 'answer', item.tempAnswer)
      this.$set(item, 'editMode', false)
      if(this.answer !=null){
        this.repCount = 1
        this.statuscheck(this.repCount)
      }
      console.log("commitAnswer" + JSON.stringfy(this.qnas))
    },

오늘도 한가지 대단한 기술을 배웠다... 계속공부하고 찾아가면서 코딩하지만 언제쯤 이렇게 될까 ㅠㅠ..


출처 : Vue.js 공식문서 - 리스트렌더링 항목
https://kr.vuejs.org/v2/guide/list.html#%EB%B0%B0%EC%97%B4-%EB%B3%80%EA%B2%BD-%EA%B0%90%EC%A7%80

profile
코더보다 개발자로, 결과와 과정의 시너지를 만들어 가고 싶은 주니어 개발자

0개의 댓글