Vue는 상태가 업로드되면 화면에 갱신됩니다. 즉, 상태의 변화에 반응을 합니다. 이것은 직관적으로 받아드릴 수 있지만 이에 대해 알아보고자 합니다.
Vue는 MVVM모델에 영감을 받아 만들어 졌습니다. 간단히 View는 DOM, VM은 Vue, Model은 JS라고 할 수 있습니다. VM은 View에 데이터 바인딩 되어 VM이 업데이트되면 View가 업데이트 됩니다. 그렇다면 어떻게 이러한 변화를 감지하고 업데이트를 하게 되는지에 대하여 알아보겠습니다.
Vue는 인스턴스에 data을 줄 경우, 안에 있는 모든 프로퍼티에 대하여 Object.defineProperty를 사용하여 getter, setter를 설정해 줍니다. 따라서 Vue가 getter, setter의 내부 로직을 구현하여 프로퍼티에 엑세스 및 수정할 경우, 종속성 추적 및 변경을 알리게 됩니다. 모든 Vue 인스턴스에는 Watcher 인스턴스가 있어, 컴포넌트가 종속적으로 렌더링 될 때, 수정된 모든 프로퍼티를 기록합니다. 후에 종속된 setter가 트리거 되다면 Watcher에 알리고 컴포넌트가 다시 렌더링 됩니다.
위 그림을 보면 이벤트에 따라서 setter가 트리거되면 Watcher가 알림 받아 트리거에 따른 다시 랜더링를 트리거하고 랜더 함수가 다시 랜더를 실행하는것을 보실 수 있습니다.
!주의점
Vue 인스턴스의 data 옵션 전달을 제외하고는 Vue의 프로퍼티의 추가, 제거는 감지할 수 없습니다. 개발하면서, 그럴일은 많이 발생하지는 않지만 JS의 한계와 Object.observe의 포기와 같은 이유로 그렇게 됩니다.
BUT!!! Vue.set(this.$set(this.obj, 'a', 2))를 이용하여, 프로퍼티를 반응형으로 추가할 수 있습니다.
Vue는 DOM 업데이트를 비동기로 합니다. 데이터 변경이 발견 될 때마다 이벤트 루프에서 발생하는 ㄴ모든 데이터 변경을 버퍼에 담아 모읍니다. 같은 Watcher가 여러 번 트리거 될 경우, 대기열에 한 번만 넣습니다. 그래서! 버퍼링 + 중복 제거로 불필요한 연산 및 DOM조작을 피할 수 있게합니다. 그래서 큐를 비우면서 DOM작업을 수행하게 됩니다.
만약 this.name = 'SCV'를 하더라도 즉시 재랜더링되지 아니하고 큐가 플러시(큐가 비워 질 때)될 때, tick에서 업데이트됩니다. 그래서 this.$nextTick(() => { //여기서 DOM이 업데이트되었음을 의미하는 것이 었습니다. })
nextTick은 Promise를 반환하여 async/await문법을 사용한 구현도할 수 있습니다.