Vue3

nextTick

덕구공 2022. 10. 27. 14:41

nextTick

  • Vue.js에서 reactive한 상태가 변할 때, 그 상태 변화에 대한 DOM 업데이트는 비동기적으로 이루어진다!
  • 아래의 예시를 살펴보자. reactive한 state가 변경되는 부분 바로 아래에 reactive한 state를 사용하는 h1 태그의 textContent를 console로 출력해보면 항상 이전의 값이 출력되는 모습을 보인다!
  • 방금 말했다시피, DOM 업데이트가 끝나기 전에 먼저 DOM에 대한 내용을 출력하기 때문이다.
<template>
  <div>
    <h1 id="count">count: {{ count }}</h1>
    <button @click="add_one">count ++</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    add_one() {
      this.count++;
      console.log(this.$el.querySelector("#count").textContent);
      // DOM 업데이트가 비동기로 실행되기 때문에 계속 이전의 값이 찍힘!
    },
  },
};
</script>

 

  • 위와 같은 문제를 nextTick을 이용해서 해결할 수 있다!
  • DOM 업데이트가 끝나야 nextTick이 실행되므로 reactive한 상태의 변화에 따른 올바른 DOM의 내용을 구 할 수 있다.
    • DOM 업데이트가 끝나기 전엔 nextTick을 제외한 다른 로직이 수행됨!

nextTick 사용해보기

  • 아래 예시를 살펴보자. nextTick의 콜백함수 내부에 reactive한 state를 사용하는 태그안의  text를 출력한다.
    • DOM 업데이트가 끝나고 출력해야 state와 같은 값이 나올 것이므로!!
  • 아래처럼 nextTick의 콜백함수에 태그 안의 text를 출력하면 DOM 업데이트가 끝난 후 실행되므로 올바른 값이 나온다
<template>
  <div>
    <h1 id="count">count: {{ count }}</h1>
    <button @click="add_one">count ++</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    add_one() {
      this.count++;
      this.$nextTick(() => {
        console.log(this.$el.querySelector("#count").textContent);
        console.log("----after DOM update----");
      });
      console.log("----before DOM update----");
      // DOM 업데이트가 끝난 후 nextTick이 실행되므로 "befor DOM udpate"가 먼저 출력!
    },
  },
};
</script>
  • 아래처럼 async/await 키워드를 이용해서 DOM 업데이트가 끝날 때까지 기다릴 수 있다!
<template>
  <div>
    <h1 id="count">count: {{ count }}</h1>
    <button @click="add_one">count ++</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    async add_one() {
      this.count++;
      console.log("----before DOM update----");
      await this.$nextTick();
      console.log(this.$el.querySelector("#count").textContent);
      console.log("----after DOM update----");
    },
  },
};
</script>