Back Ground

Vue - $nextTick 본문

Javascript/Vue.js

Vue - $nextTick

Back 2019. 4. 16. 23:12

Vue에서 데이터와 UI를 건드려야 하는 상황에

DOM을 못 찾는 상황이 생긴다.

 

데이터를 통해 만들어진 DOM이 완성되기 전 호출을 하려고 하는 상황인데

어떤 데이터를 vue._data에 삽입하자마자 삽입 후 갱신 될 DOM을 찾아 처리하려고 하면

DOM을 찾지 못한다는 에러 문구만 나올 뿐이다.

 

모든 데이터처리가 비동기로 처리되는 Javascript의 특성 때문에 DOM이 갱신되기 전 탐색하는 상황이 나오게된다.

 

 

오류 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<div id="app">
    <div v-for="item in list">
        <div v-bind:id="bindId(item)"></div>    <!-- 2 -->
    </div>
</div>
 
<script>
new Vue({
    el: '#app',
    data: function() {
        return {
            list: []
        };
    },
    created: function() {
        var self = this;
 
        for(var i=0; i<100; i++) {
            this._data.list.push(i);    // 1
        }
 
        var dom = document.getElementById('item-0');    // 4
        dom.style.backgroundColor = 'red';                // 5
    },
    methods: {
        bindId: function(item) {
            return 'item-' + item;    // 3
        }
    }
})
</script>
cs

위와 같은 상황으로 작성하게 되면 오류가 나게 된다.

간단하게 설명을 드리면 1에서 list에 데이터들을 넣게 된다.
Vue.js는 이를 감지하여 
2, 3을 통해 UI들을 갱신하게 되는데,
UI를 갱신하기전에 
1의 다음 라인인 4,5를 수행하게 된다.

아직 그리지도 않은 UI를 호출하려하니 당연히 오류가 난다.

Vue.js에서는 이런 일이 일어날 것을 예측하고, callback함수를 제공하고 있다.

 

 

 

$nextTick

 

1
2
3
4
5
6
7
8
9
created: function() {
 
    // ...
 
    this.$nextTick(function() {
        var dom = document.getElementById('item-0');
        dom.style.backgroundColor = 'red';
    });
}
cs

 

nextTick으로 감싼뒤 callback을 통해 DOM을 조작하게 되면 

Vue.js에서 데이터갱신 후 UI까지 완료한 뒤에 nextTick에 있는 함수를 최종적으로 수행하게 된다.

 

참고문서 : https://kr.vuejs.org/v2/api/#Vue-nextTick

 

 

 
 

사용 방식

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
      this.$nextTick( ()=>{
        let parentEl = this.$el.querySelector('#cat-'+this.catDetailInfo.parent);
        if(this.getAttrNumber(parentEl,'level'!== 1){
          let bool = true;
          while (bool) {
            ifthis.getAttrNumber(parentEl,'level'== 2){
              parentEl = this.$el.querySelector('#'+parentEl.id);
              this.accordionEvent(parentEl, 'dropDown');
              bool = false;
            }else{
              parentEl = this.$el.querySelector('#cat-'+this.getAttrNumber(parentEl,'parent'));
            }
          }
        }
      });
cs

 

'Javascript > Vue.js' 카테고리의 다른 글

Vue - 라이프 사이클  (0) 2019.06.27
Vue - 인스턴스  (0) 2019.03.15
Vue - Directive(지시문)  (1) 2019.03.13
Vue - Mustache(콧수염) 템플릿  (0) 2019.03.13
Vue - Vue란  (0) 2019.03.13
Comments