재우니의 블로그

 

웹 페이지의 구조를 나타내는 HTML 문서는 일련의 요소들로 구성되어 있습니다. 이러한 요소들은 'Document Object Model' 혹은 줄여서 'DOM'이라고 부릅니다.

브라우저는 HTML 문서를 로드할 때 DOM을 생성하고, 이후에 JavaScript를 통해 DOM 요소를 추가, 삭제, 수정하는 등의 동작을 수행하며 페이지를 업데이트합니다. 이러한 과정을 'DOM 업데이트'라고 합니다.

그런데 JavaScript는 브라우저에서 비동기적으로 동작하는 경우가 많습니다. 즉, 코드가 순차적으로 실행되는 것이 아니라, 특정 코드의 실행이 완료되기를 기다리지 않고 다음 코드를 실행하게 됩니다. 따라서 JavaScript로 DOM 요소를 추가, 삭제, 수정하는 코드를 작성했다고 해서 바로 DOM이 업데이트되는 것은 아닙니다.

예를 들어, Vue.js에서 데이터를 변경하면 이에 따라 DOM이 업데이트되지만, 이 업데이트는 즉시 발생하는 것이 아니라 Vue.js의 '다음 업데이트 사이클'에서 발생합니다. 즉, 데이터를 변경한 직후에는 DOM이 아직 업데이트되지 않은 상태입니다.

Vue.js의 this.$nextTick 메소드를 사용하면, DOM 업데이트가 완료된 직후에 코드를 실행할 수 있습니다. 이 메소드에 콜백 함수를 전달하면, Vue.js는 DOM 업데이트가 완료된 후에 해당 콜백 함수를 실행합니다. 이를 통해 DOM 업데이트가 완료된 상태에서 필요한 동작을 수행할 수 있습니다.

 

 

Vue.js에서 this.$nextTick은 DOM 업데이트가 완료된 직후에 콜백을 실행하기 위해 사용됩니다. mounted 라이프사이클 훅에서 this.$nextTick을 사용하는 예제를 아래에 제공하겠습니다.

아래 예제에서는 mounted 라이프사이클 훅 내에서 this.$nextTick을 사용하여 DOM 업데이트가 완료된 후에 focusInput 메소드를 호출합니다. focusInput 메소드는 ref="myInput"으로 지정된 input 요소에 포커스를 주는 역할을 합니다.

 

new Vue({
  el: '#app',
  data: {
    message: ''
  },
  methods: {
    focusInput() {
      this.$refs.myInput.focus();
    }
  },
  mounted() {
    this.$nextTick(function () {
      this.focusInput();
    })
  }
});

 

이 예제에서는 Vue 인스턴스가 마운트된 후에 input 요소에 포커스를 주는 것을 확인할 수 있습니다. this.$nextTick을 사용하지 않는 경우, DOM 업데이트가 아직 완료되지 않은 상태에서 focusInput 메소드를 호출하게 되므로 예상한 대로 동작하지 않을 수 있습니다.

 

new Vue({
  el: '#app',
  data: {
    message: 'Hello, Vue!'
  },
  mounted() {
    console.log(this.$refs.myDiv.innerText); // 아직 업데이트되지 않은 상태
    this.message = 'Hello, World!';
    this.$nextTick(() => {
      console.log(this.$refs.myDiv.innerText); // 'Hello, World!'
    });
  }
});


<div id="app">
  <div ref="myDiv">{{ message }}</div>
</div>

 

 

위의 코드에서 this.$nextTick을 사용하지 않으면, this.$refs.myDiv.innerText는 아직 업데이트되지 않은 상태의 값을 출력합니다. this.$nextTick을 사용하면, this.$refs.myDiv.innerText는 업데이트된 상태의 값을 출력합니다.

 

new Vue({
  el: '#app',
  data: {
    items: ['Apple', 'Banana', 'Cherry']
 },
  methods: {
    addItem() {
      this.items.push('Durian');
      console.log(this.$refs.list.children.length); // 아직 업데이트되지 않은 상태
      this.$nextTick(() => {
        console.log(this.$refs.list.children.length); // 4
      });
    }
  },
  mounted() {
    this.addItem();
  }
});

<div id="app">
  <ul ref="list">
    <li v-for="item in items" :key="item">{{ item }}</li>
  </ul>
</div>

 

위의 코드에서 this.$nextTick을 사용하지 않으면, this.$refs.list.children.length는 아직 업데이트되지 않은 상태의 값을 출력합니다. this.$nextTick을 사용하면, this.$refs.list.children.length는 업데이트된 상태의 값을 출력합니다.

 


 

다른 경우로는 비동기적으로 데이터를 가져오는 경우를 들 수 있습니다.

예를 들어, $.ajax를 사용하여 데이터를 가져온 후 Vue.js 인스턴스의 데이터를 업데이트하고, 이 업데이트가 DOM에 반영된 이후에 추가 작업을 수행하려는 경우에 this.$nextTick을 사용할 수 있습니다.

다음은 이러한 사용 사례를 나타내는 코드 예제입니다:

 

new Vue({
  el: '#app',
  data: {
    items: []
  },
  methods: {
    fetchData() {
      $.ajax({
        url: 'http://example.com/api/items',
        method: 'GET',
        success: (data) => {
          this.items = data;
          this.$nextTick(() => {
            console.log('DOM 업데이트 완료');
            // 이 시점에서 DOM은 새로운 items에 따라 업데이트되었습니다.
            // 추가 작업을 수행하세요.
          });
        }
      });
    }
  },
  mounted() {
    this.fetchData();
  }
});

 

이 코드에서 fetchData 메소드는 $.ajax를 사용하여 비동기적으로 데이터를 가져옵니다. success 콜백에서는 가져온 데이터를 this.items에 할당하고, 이 변경이 DOM에 반영된 이후에 추가 작업을 수행합니다. 이 때 this.$nextTick을 사용하여 DOM 업데이트가 완료된 이후에 실행될 콜백을 등록합니다.