티스토리 뷰
Vue의 가장 두드러지는 특징 중 하나는 눈에 띄지 않는 반응형 시스템입니다. 모델은 단순한 JavaScript 객체입니다. 모델이 수정되면 화면이 갱신됩니다. 이번 포스트에서 이러한 반응형 시스템을 좀 더 자세히 알아보려고 합니다.
1. MVVM 패턴
Vue는 MVVM 패턴에 영감을 받은 프레임워크입니다.
위의 그림은 MVVM 패턴을 나타내는 그림입니다. 더 자세한 설명은 [디자인패턴] MVC, MVP, MVVM 비교를 참고 바랍니다.
View는 DOM, View Model은 Vue, Model은 단순한 JavaScript 객체 입니다. View Model은 View와 데이터 바인딩되어 View Model이 변경 되 었을 때 View가 업데이트 됩니다.
2. 변경 내용을 추적하는 방법
Vue 인스턴스에 data
옵션을 포함하는 JavaScript 객체를 전달하면 Vue는 모든 속성에 Object.defineProperty를 사용하여 getter/setter로 변환합니다. 이것이 Vue는 ES5를 사용할 수 없는 IE8 이하를 지원하지 않는 이유입니다.
getter/setter는 사용자에게는 보이지 않지만 속성에 접근하거나 수정할 때 Vue가 종속성 추적 및 변경 알림을 수행할 수 있습니다.
모든 컴포넌트 인스턴스에는 해당 watcher 인스턴스가 있으며, 이 인스턴스는 컴포넌트가 종속적으로 렌더링되는 동안 수정된 모든 속성을 기록합니다. 또한 종속적인 setter가 트리거 되면 watcher에 알리고 컴포넌트가 다시 랜더링됩니다.
3. 변경 감지 경고
최신 JavaScript의 한계(Object.observe
의 포기)로 인해 Vue는 속성의 추가 체거를 감지 할 수 없습니다. Vue는 인스턴스 초기화 할 때 getter/setter 변환 과정을 수행하기 때문에 data 객체에 속성이 있어서 Vue가 변경사항을 감지할 수 있습니다.
var vm = new Vue({
data: {
a: 1
}
})
// `vm.a` 은 이제 반응적입니다.
vm.b = 2
// `vm.b` 은 이제 반응적이지 않습니다.
이미 만들어진 인스턴스에 반응 속성을 동적으로 추가하는 것을 허용하지 않지만, Vue.set(object, key, value)
메소드를 사용하여 중첩 된 객체에 반응성 속성을 추가 할 수 있습니다.
Vue.set(vm.someObject, 'b', 2)
위의 코드와 같이 루트 수준의 중첩 된 객체에 반응성 속성을 추가할 수 있습니다.
this.$set(this.someObject, 'b', 2)
위의 코드는 Vue.set
에 별칭으로 this.$set
을 사용한 코드입니다.
4. 반응형 속성 선언하기
Vue는 반응성 속성을 동적으로 추가 할 수 없기 때문에 반응성 테이터 속성을 빈 값으로라도 초기에 선언하여 Vue 인스턴스를 초기화 해야 합니다.
var vm = new Vue({
data: {
// 빈 값으로 메시지를 선언 합니다.
message: ''
},
template: '{{ message }}'
})
// 나중에 `message`를 설정합니다.
vm.message = 'Hello!'
data
옵션에 message
를 선언하지 않으면 Vue의 render 함수는 존재하지 않는 속성에 접근하려고 한다는 경고를 발생시킵니다. 모든 반응 속성을 미리 선언하면 나중에 다른 개발자가 코드를 분석 할 때 코드를 더 쉽게 이해 할 수 있습니다.
5. 비동기 갱신 큐
Vue는 DOM 업데이트를 비동기로 동작합니다. 모든 데이터 변경 사항은 버퍼링됩니다. 즉 동일한 watcher가 여러번 트리거 되더라고 한번만 큐에 푸시 됩니다. 이 버퍼링은 중복된 변경 사항의 불필요한 계산을 줄이고, DOM 조작을 최소화하기 때문에 중요합니다. 그 후에는 이벤트 루프 tick에서 Vue는 큐를 비우고 실제 DOM에 작업(버퍼링으로 중복이 제거된 작업)을 수행합니다.
예를 들어, vm,someDate = 'new value'
를 설정하면, 컴포넌트는 즉시 재 랜더링하지 않습니다. 다음 tick에서 업데이트 됩니다. 대부분의 경우에는 이 작업을 신경 쓸 필요는 없지만, 업데이트 된 후 DOM 상태에 의존적인 작업을 하기 위해서는 까다로울 수 있습니다. Vue는 일반적으로 개발자가 데이터 중심적으로 개발하고 DOM을 직접 수정하지 않는 것을 권장하지만 때로는 직접 DOM을 수정해야 필요도 있습니다.
Vue가 DOM을 업데이트 된 후의 DOM을 보장하기 위해서는 Vue.nextTick(callback)
을 사용하면 됩니다. 이 callback
은 DOM이 업데이트 된 후에 호출 되기 때문에 DOM이 업데이트 된 이후임을 보장할 수 있습니다.
<div id="example">{{ message }}</div>
var vm = new Vue({
el: '#example',
data: {
message: '123'
}
})
vm.message = 'new message' // 데이터 변경
vm.$el.textContent === 'new message' // false
Vue.nextTick(function () {
vm.$el.textContent === 'new message' // true
})
또한 this.$nextTick()
메소드를 제공합니다. 이 메소드는 컴포넌트 인스턴스에서 사용할 때 유용합니다.
Vue.component('example', {
template: '{{ message }}',
data: function () {
return {
message: '갱신 안됨'
}
},
methods: {
updateMessage: function () {
this.message = '갱신됨'
console.log(this.$el.textContent) // => '갱신 안됨'
this.$nextTick(function () {
console.log(this.$el.textContent) // => '갱신됨'
})
}
}
})
참고
'Vue.JS' 카테고리의 다른 글
[vue-router] 동적 라우트 매칭 (0) | 2019.06.09 |
---|---|
[vue-router] 시작하기 (0) | 2019.06.06 |
[Vue.JS] 필터 (2) | 2019.02.19 |
[Vue.JS] 플러그인 (0) | 2019.02.18 |
[Vue.JS] Render Functions & JSX (0) | 2019.02.14 |