nextTick은 무엇이며 VueJs에서 수행하는 작업


104

문서를 읽었지만 이해할 수 없습니다. 나는 어떤 데이터, 계산, 감시, 방법을 알고 있지만 nextTick()vuejs에서 무엇을 사용합니까?


17
이해해야 할 핵심 개념은 DOM이 비동기 적 으로 업데이트된다는 것입니다 . Vue에서 값을 변경하면 변경 사항이 DOM에 즉시 렌더링 되지 않습니다 . 대신 Vue는 DOM 업데이트를 큐에 넣은 다음 타이머에서 DOM을 업데이트합니다. 일반적으로 이것은 매우 빠르게 발생하여 차이를 만들지 않지만, 때때로 Vue가 렌더링 한 후 렌더링 된 DOM을 업데이트해야합니다. 업데이트가 발생하지 않았기 때문에 메서드에서 즉시 수행 할 수 없습니다. 아직. 이 경우 nextTick. 여기에 문서화되어 있습니다 .
Bert

위의 https://stackoverflow.com/q/47634258/9979046 에서 @Bert가 말한 것을 보완 하면, 예를 들어 DOM (HTML)에 요소가 있는지 확인해야 할 때 단위 테스트에서 nextTick ()이 사용됩니다. Axios 요청에 대한 정보를 얻을 수 있습니다.
Oscar Alencar

답변:


139

nextTick을 사용하면 데이터를 변경하고 VueJS가 데이터 변경을 기반으로 DOM을 업데이트 한 후 브라우저가 변경 사항을 페이지에 렌더링하기 전에 작업을 수행 할 수 있습니다.

일반적으로 개발자는 네이티브 JavaScript 함수 인 setTimeout사용 하여 유사한 동작을 수행합니다. setTimeout그러나을 사용 하면 콜백을 통해 다시 제어권을 제공하기 전에 브라우저에 대한 제어권이 포기됩니다.

일부 데이터를 변경했다고 가정 해 보겠습니다. Vue는 데이터를 기반으로 DOM을 업데이트합니다. DOM 변경 사항은 아직 브라우저에 의해 화면에 렌더링되지 않습니다. 을 사용한 경우 nextTick지금 콜백이 호출됩니다. 그런 다음 브라우저가 페이지를 업데이트합니다. 을 사용한 경우 setTimeout콜백은 지금 만 호출됩니다.

다음과 같은 작은 구성 요소를 만들어이 동작을 시각화 할 수 있습니다.

<template>
  <div class="hello">
    {{ msg }}
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
        msg: 'One'
    }
  },
  mounted() {
      this.msg = 'Two';

      this.$nextTick(() => {
          this.msg = 'Three';
      });
  }
}
</script>

로컬 서버를 실행하십시오. 메시지 Three가 표시됩니다.

이제 다음으로 교체하십시오 this.$nextTick.setTimeout

setTimeout(() => {
    this.msg = 'Three';
}, 0);

브라우저를 다시로드하십시오. 당신이보기 Two전에 당신은 보게 될 것 Three입니다.

라이브보려면 이 바이올린을 확인하세요.

Vue가 DOM을으로 업데이트 Two하여 브라우저에 제어권을 부여 했기 때문 입니다. 브라우저가 표시됩니다 Two. 그런 다음 콜백을 호출하십시오. Vue는 DOM을 Three. 브라우저가 다시 표시됩니다.

nextTick. Vue는 DOM을 Two. 콜백을 호출했습니다. Vue는 DOM을 Three. 그런 다음 브라우저를 제어했습니다. 그리고 브라우저에 Three.

분명했기를 바랍니다.

Vue가이를 구현하는 방법을 이해하려면 Event Loopmicrotasks 의 개념을 이해해야합니다 .

이러한 개념이 명확 해지면 nextTick소스 코드를 확인하십시오 .


4
내가 이해하지 못하는 한 가지는 "vue updates the data"라고 말할 때 ex :로 만든 업데이트 this.name = 'foo'를 참조하고 있습니까? 아니면 페이지에 html 요소 삽입을 참조하고 있습니까?
hidar

나는이 질문의 역사에서 그가 "vue가 데이터를 업데이트한다"라고 말하는 곳을 보지 못합니다. 그는 "Vue가 데이터를 기반으로 DOM을 업데이트합니다"라고 말합니다. 즉, this.name = 'foo'vue 를 통해 데이터를 설정할 때 구성한 템플릿 및 기능을 기반으로 데이터에 대한 변경 사항을 반영하도록 문서 개체 모델을 업데이트합니다.
ADJenks

24

콘텐츠는 By Adrià Fontcuberta 에서 가져 왔습니다.

Vue 문서는 다음과 같이 말합니다.

Vue.nextTick ([콜백, 컨텍스트])

다음 DOM 업데이트주기 후에 콜백이 실행되도록 연기합니다. DOM 업데이트를 기다리기 위해 일부 데이터를 변경 한 후 즉시 사용하십시오.

흠 ... 처음에 겁이 나더라도 걱정하지 말고 최대한 간단하게 설명하겠습니다. 하지만 먼저 알아야 할 두 가지 사항이 있습니다.

  1. 그 사용법은 흔하지 않습니다. 은색 마법 카드 중 하나처럼. 여러 Vue앱 을 작성 하고 nextTick ()을 한두 번 만났습니다.

  2. 실제 사용 사례를 살펴보면 이해하기가 더 쉽습니다. 아이디어를 얻은 후에는 두려움이 사라지고 벨트 아래에 편리한 도구가 있습니다.

그럼 가자.

$ nextTick 이해

우리는 프로그래머 죠? 우리는 사랑하는 분할 및 정복 접근 방식을 사용하여 설명을 .nextTick()조금씩 번역하려고 노력할 것 입니다. 다음으로 시작합니다.

콜백 연기

좋아, 이제 우리는 콜백을 수락한다는 것을 알고 있습니다. 따라서 다음과 같이 보입니다.

Vue.nextTick(function () {
  // do something cool
});

큰. 이 콜백은 다음까지 연기됩니다 (밀레 니얼 세대가 지연되었다고 말하는 방식입니다).

다음 DOM 업데이트주기.

괜찮아. 우리는 Vue가 DOM 업데이트를 비동기 적으로 수행 한다는 것을 알고 있습니다. 업데이트를 적용해야 할 때까지 이러한 업데이트를 "저장"하는 방법이 있습니다. 업데이트 대기열을 만들고 필요할 때 플러시합니다. 그런 다음 DOM이 "패치"되고 최신 버전으로 업데이트됩니다.

뭐?

다시 시도해 보겠습니다. this.potatoAmount = 3.Vue가 구성 요소 (및 DOM)를 자동으로 다시 렌더링하지 않는 것처럼 구성 요소가 정말 필수적이고 스마트 한 작업을 수행한다고 상상해보십시오 . 필요한 수정을 대기열에 추가합니다. 그런 다음 다음 "틱"(시계에서와 같이)에서 큐가 플러시되고 업데이트가 적용됩니다. 타다!

괜찮아! 따라서 데이터가 설정되고 DOM이 업데이트 된 직후에nextTick() 실행되는 콜백 함수를 전달하는 데 사용할 수 있다는 것을 알고 있습니다 .

앞서 말했듯이 ... 그렇게 자주는 아닙니다. Vue, React 및 Google의 다른 하나를 구동하는 "데이터 흐름"접근 방식은 언급하지 않겠지 만 대부분의 경우 불필요하게 만듭니다. 그러나 때로는 일부 요소가 DOM에서 나타나거나 사라지거나 수정 될 때까지 기다려야합니다. 이것은 nextTick이 유용 할 때입니다.

DOM 업데이트를 기다리기 위해 일부 데이터를 변경 한 후 즉시 사용하십시오.

바로 그거죠! 이것은 Vue 문서가 우리에게 제공 한 마지막 정의입니다. 콜백 내에서 DOM이 업데이트되어 "가장 업데이트 된"버전과 상호 작용할 수 있습니다.

증명

좋아요, 좋아요. 콘솔을 보면 데이터 값이 nextTick의 콜백 내에서만 업데이트되는 것을 볼 수 있습니다.

const example = Vue.component('example', {
  template: '<p>{{ message }}</p>',
  data: function () {
    return {
      message: 'not updated'
    }
  },
  mounted () {
    this.message = 'updated'

        console.log(
        'outside nextTick callback:', this.$el.textContent
    ) // => 'not updated'

    this.$nextTick(() => {
      console.log(
        'inside nextTick callback:', this.$el.textContent
      ) // => 'not updated'
    })
  }
})


new Vue({
  el: '#app',
    render: h => h(example)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.10/vue.js"></script>
<div id="app"></div>

사용 사례

에 대한 유용한 사용 사례를 정의 해 보겠습니다 nextTick.

구성 요소가 마운트 될 때 몇 가지 작업을 수행해야한다고 상상해보십시오. 그러나! 구성 요소뿐만 아니라. 또한 모든 하위 항목이 DOM에서 마운트되고 사용 가능할 때까지 기다려야합니다. 제길! 마운트 된 후크는 전체 구성 요소 트리가 렌더링되는 것을 보장하지 않습니다.

다음 DOM 업데이트주기를 기다릴 도구가 있다면…

하하 :

mounted() {
  this.$nextTick(() => {
    // The whole view is rendered, so I can safely access or query
    // the DOM. ¯\_(ツ)_/¯
  })
}

간단히 말해서

따라서 : nextTick데이터가 설정되고 DOM이 업데이트 된 후 함수를 실행하는 편리한 방법입니다.

DOM을 기다려야합니다. 변환을 수행해야하거나 외부 라이브러리가 해당 항목을로드 할 때까지 기다려야하기 때문일 수 있습니다. 그런 다음 nextTick을 사용하십시오.

어떤 사람들은 또한 데이터가 업데이트되었는지 확인하기 위해 단위 테스트에서 nextTick을 사용합니다. 이렇게하면 구성 요소의 "업데이트 된 버전"을 테스트 할 수 있습니다.

Vue.nextTick () 또는 vm. $ nextTick ()?

걱정하지 마세요. 둘 다 (거의) 동일합니다. Vue.nextTick()글로벌 API 메소드를 참조 vm.$nextTick()하고 인스턴스 메소드입니다. 유일한 차이점은 vm.$nextTick컨텍스트를 두 번째 매개 변수로 받아들이지 않는다는 것입니다. 항상 바인딩됩니다 this(인스턴스 자체라고도 함).

시원함의 마지막 조각

nextTick반환 Promise하므로 async/await예제를 완벽하게 개선하고 개선 할 수 있습니다 .

async mounted () {
    this.message = 'updated'
    console.log(this.$el.textContent) // 'not updated'
    await this.$nextTick()
    console.log(this.$el.textContent) // 'updated'
}

2
"귀하의"설명 상단에 원본 작성자와 링크를 추가하기 만하면됩니다.
Renan Cidale

1
얼마나 놀라운 설명입니까! 시간과 노력에 감사드립니다.
Muaath Alhaddad

16

Next Tick은 기본적으로 반응 속성 (데이터)을 일부 변경했을 때 vue가 구성 요소를 다시 렌더링 한 후 일부 코드를 실행할 수 있도록합니다.

// modify data
vm.msg = 'Hello'
// DOM not updated yet
Vue.nextTick(function () {
  // this function is called when vue has re-rendered the component.
})

// usage as a promise (2.1.0+, see note below)
Vue.nextTick()
  .then(function () {
      // this function is called when vue has re-rendered the component.
})

Vue.js 문서에서 :

다음 DOM 업데이트주기 후에 콜백이 실행되도록 연기합니다. DOM 업데이트를 기다리기 위해 일부 데이터를 변경 한 후 즉시 사용하십시오.

여기에서 자세히 알아 보세요 .


2
어떻게 업데이트합니까? 이것은 내가 이해하지 않는 것입니다. vm.msg를 업데이트하면 새 텍스트 ''hello "..가 있으므로 DOM이 이미 업데이트 된 것입니다. 그래서 어떻게 다시 업데이트 할 수 있습니까? 예제 pls와 함께 바이올린을 게시 할 수 있습니까? 감사합니다
hidar

네, 답을 수정하고 더 자세히 설명하겠습니다.
Daksh Miglani

@hidar 여러 업데이트를해야 할 때 상황에 사용할 수 있습니다,하지만 당신은 명시 적으로 다른 DOM주기에서 서로를 렌더링 할
Daksh Miglani

DOM 자체 를 업데이트 할 수있는 것이 아니라 Vue가 수행 한 변경 사항에 의해 영향을 받거나 수정 된 후에 (업데이트, 정보 읽기 등) 무엇이든 할 수 있습니다 (반응 속성 값을 변경했기 때문에 등).
zenw0lf

그것은 더 간단하게 만드는 예였습니다.
Daksh Miglani

7

더 명시 nextTick과의 setTimeout을 사용 사이의 차이에 대한 Pranshat의 답변을하기 위해, 나는 그의 바이올린 포크했다 : 여기

mounted() {    
  this.one = "One";
 
  setTimeout(() => {
    this.two = "Two"
  }, 0);
  
  //this.$nextTick(()=>{
  //this.two = "Two"
  //})}

setTimeOut을 사용할 때 변경 사항을 적용하기 전에 구성 요소가 마운트되면 초기 데이터가 매우 짧게 깜박이는 것을 바이올린에서 볼 수 있습니다. 반면에 nextTick을 사용하면 브라우저에 렌더링하기 전에 데이터가 하이재킹되고 변경됩니다. 따라서 브라우저는 이전에 대한 지식도없이 업데이트 된 데이터를 표시합니다. 두 가지 개념이 한 번에 해결되기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.