웹 프론트엔드 JS 튜토리얼 Vue의 nextTick 메소드에 대한 자세한 소개

Vue의 nextTick 메소드에 대한 자세한 소개

Jun 08, 2018 pm 05:40 PM
nexttick vue

이 글은 주로 Vue의 nextTick 메소드에 대한 간단한 이해를 소개하며, 참고용으로 공유합니다.

Vue의 nextTick은 Vue의 DOM 비동기 업데이트와 관련되어 있으며 매우 흥미롭고 특별히 배웠습니다. nextTick의 소스 코드에는 많은 지식이 포함되어 있으며 그 중 많은 부분이 제가 잘 이해하지 못하는 부분도 있습니다. 저의 통찰력을 바탕으로 nextTick을 소개하겠습니다.

1. 예제

먼저 Vue의 DOM 업데이트와 nextTick의 역할에 대해 알아보기 위해 예제를 살펴보겠습니다.

Template

<p class="app">
 <p ref="msgp">{{msg}}</p>
 <p v-if="msg1">Message got outside $nextTick: {{msg1}}</p>
 <p v-if="msg2">Message got inside $nextTick: {{msg2}}</p>
 <p v-if="msg3">Message got outside $nextTick: {{msg3}}</p>
 <button @click="changeMsg">
  Change the Message
 </button>
</p>
로그인 후 복사

Vue 인스턴스

new Vue({
 el: &#39;.app&#39;,
 data: {
  msg: &#39;Hello Vue.&#39;,
  msg1: &#39;&#39;,
  msg2: &#39;&#39;,
  msg3: &#39;&#39;
 },
 methods: {
  changeMsg() {
   this.msg = "Hello world."
   this.msg1 = this.$refs.msgp.innerHTML
   this.$nextTick(() => {
    this.msg2 = this.$refs.msgp.innerHTML
   })
   this.msg3 = this.$refs.msgp.innerHTML
  }
 }
})
로그인 후 복사

클릭 전

클릭 후

그림을 보면 알 수 있습니다. msg1과 msg3에 표시된 내용은 아직 변환 전이고 표시된 내용은 msg2는 그 이후의 변환입니다. 근본적인 이유는 Vue의 DOM 업데이트가 비동기식이라는 것입니다(자세한 설명은 아래 참조).

2. 애플리케이션 시나리오

nextTick의 주요 애플리케이션 시나리오와 이유에 대해 알아 보겠습니다.

Vue 라이프사이클의 Created() 후크 함수에서 수행되는 DOM 작업은 Vue.nextTick()의 콜백 함수에 배치되어야 합니다.

DOM은 Created() 후크 함수가 실행될 때 실제로 전혀 렌더링되지 않으며, 이때 DOM 작업을 수행하는 것은 쓸데없는 일이므로 여기서는 DOM 작업을 위한 js 코드를 Vue.nextTick()의 콜백 함수에 넣어야 합니다. 이에 대응하는 것이 Mounted() Hook 함수인데, Hook 함수가 실행되면 모든 DOM Mounting과 Rendering이 완료되기 때문에 Hook 함수에서는 DOM 연산을 수행하는데 문제가 없을 것입니다.

데이터 변경 후 작업을 수행해야 하고, 이 작업에 데이터 변경에 따라 변경되는 DOM 구조를 사용해야 하는 경우 이 작업을 Vue.nextTick()의 콜백 함수에 넣어야 합니다.

구체적인 이유는 Vue의 공식 문서에 자세히 설명되어 있습니다.

Vue는 DOM 업데이트를 비동기식으로 수행합니다. 데이터 변경이 관찰될 때마다 Vue는 대기열을 열고 동일한 이벤트 루프에서 발생하는 모든 데이터 변경 사항을 버퍼링합니다. 동일한 감시자가 여러 번 트리거되면 대기열에 한 번만 푸시됩니다. 버퍼링 중 이러한 중복 제거는 불필요한 계산 및 DOM 작업을 방지하는 데 중요합니다. 그런 다음 다음 이벤트 루프 "틱"에서 Vue는 큐를 플러시하고 실제(중복 제거된) 작업을 수행합니다. Vue는 내부적으로 비동기 대기열에 기본 Promise.then 및 MessageChannel을 사용하려고 시도합니다. 실행 환경이 이를 지원하지 않으면 대신 setTimeout(fn, 0)이 사용됩니다.

예를 들어 vm.someData = 'new value'를 설정하면 구성 요소가 즉시 다시 렌더링되지 않습니다. 큐가 플러시되면 이벤트 루프 큐가 지워지는 다음 "틱"에서 구성 요소가 업데이트됩니다. 대부분의 경우 이 프로세스에 대해 걱정할 필요가 없지만 DOM 상태가 업데이트된 후에 뭔가를 하려는 경우 약간 까다로울 수 있습니다. Vue.js는 일반적으로 개발자가 "데이터 기반" 방식으로 생각하고 DOM을 직접 건드리지 않도록 권장하지만 실제로 그렇게 해야 할 때가 있습니다. 데이터 변경 후 Vue가 DOM 업데이트를 완료할 때까지 기다리려면 데이터 변경 직후 Vue.nextTick(콜백)을 사용할 수 있습니다. 이 콜백 함수는 DOM 업데이트가 완료된 후에 호출됩니다.

3. nextTick 소스 코드에 대한 간략한 분석

기능

Vue.nextTick은 2개의 매개변수(콜백 함수 및 콜백 함수 실행을 위한 컨텍스트)를 허용합니다. 콜백 함수가 제공되지 않으면 Promise 객체가 반환됩니다.

소스 코드

/**
 * Defer a task to execute it asynchronously.
 */
export const nextTick = (function () {
 const callbacks = []
 let pending = false
 let timerFunc

 function nextTickHandler () {
  pending = false
  const copies = callbacks.slice(0)
  callbacks.length = 0
  for (let i = 0; i < copies.length; i++) {
   copies[i]()
  }
 }

 // the nextTick behavior leverages the microtask queue, which can be accessed
 // via either native Promise.then or MutationObserver.
 // MutationObserver has wider support, however it is seriously bugged in
 // UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It
 // completely stops working after triggering a few times... so, if native
 // Promise is available, we will use it:
 /* istanbul ignore if */
 if (typeof Promise !== &#39;undefined&#39; && isNative(Promise)) {
  var p = Promise.resolve()
  var logError = err => { console.error(err) }
  timerFunc = () => {
   p.then(nextTickHandler).catch(logError)
   // in problematic UIWebViews, Promise.then doesn&#39;t completely break, but
   // it can get stuck in a weird state where callbacks are pushed into the
   // microtask queue but the queue isn&#39;t being flushed, until the browser
   // needs to do some other work, e.g. handle a timer. Therefore we can
   // "force" the microtask queue to be flushed by adding an empty timer.
   if (isIOS) setTimeout(noop)
  }
 } else if (!isIE && typeof MutationObserver !== &#39;undefined&#39; && (
  isNative(MutationObserver) ||
  // PhantomJS and iOS 7.x
  MutationObserver.toString() === &#39;[object MutationObserverConstructor]&#39;
 )) {
  // use MutationObserver where native Promise is not available,
  // e.g. PhantomJS, iOS7, Android 4.4
  var counter = 1
  var observer = new MutationObserver(nextTickHandler)
  var textNode = document.createTextNode(String(counter))
  observer.observe(textNode, {
   characterData: true
  })
  timerFunc = () => {
   counter = (counter + 1) % 2
   textNode.data = String(counter)
  }
 } else {
  // fallback to setTimeout
  /* istanbul ignore next */
  timerFunc = () => {
   setTimeout(nextTickHandler, 0)
  }
 }

 return function queueNextTick (cb?: Function, ctx?: Object) {
  let _resolve
  callbacks.push(() => {
   if (cb) {
    try {
     cb.call(ctx)
    } catch (e) {
     handleError(e, ctx, &#39;nextTick&#39;)
    }
   } else if (_resolve) {
    _resolve(ctx)
   }
  })
  if (!pending) {
   pending = true
   timerFunc()
  }
  if (!cb && typeof Promise !== &#39;undefined&#39;) {
   return new Promise((resolve, reject) => {
    _resolve = resolve
   })
  }
 }
})()
로그인 후 복사

먼저 nextTick에 정의된 세 가지 중요한 변수를 이해해 보겠습니다.

  1. callbacks: 실행해야 하는 모든 콜백 함수를 저장하는 데 사용됩니다.

  2. pending: 콜백 함수가 실행되고 있는지 표시하는 데 사용됩니다.

  3. timerFunc: 콜백 함수의 실행을 트리거하는 데 사용됩니다.

다음으로 nextTickHandler()함수에 대해 알아보세요.

function nextTickHandler () {
  pending = false
  const copies = callbacks.slice(0)
  callbacks.length = 0
  for (let i = 0; i < copies.length; i++) {
   copies[i]()
  }
 }
로그인 후 복사

이 함수는 콜백에 저장된 모든 콜백 함수를 실행하는 데 사용됩니다.

다음 단계는 TriggerFunc에 트리거 메서드를 할당하는 것입니다.

먼저 Promise가 기본적으로 지원되는지 확인하세요. 그렇다면 Promise를 사용하여 콜백 함수 실행을 시작하세요.

그렇지 않으면 MutationObserver가 지원되면 관찰자 개체를 인스턴스화하고 변경 사항을 관찰할 때 모든 콜백 함수 실행을 실행하세요. 텍스트 노드.

둘 다 지원되지 않으면 setTimeout을 사용하여 지연을 0으로 설정하세요.

마지막으로 queueNextTick 함수입니다. nextTick은 즉각적인 함수이기 때문에 queueNextTick 함수는 사용자가 전달한 매개변수를 받아들이고 콜백에 콜백 함수를 저장하는 데 사용되는 반환 함수입니다.

위 그림은 전체 실행 과정을 보여주고 있는데, 핵심은 실행을 지연시키는 기능인 timeFunc()에 있습니다.

위의 소개에서 timeFunc()의 구현 방법에는 세 가지가 있음을 알 수 있습니다.

  1. Promise

  2. MutationObserver

  3. setTimeout

其中Promise和setTimeout很好理解,是一个异步任务,会在同步任务以及更新DOM的异步任务之后回调具体函数。

下面着重介绍一下MutationObserver。

MutationObserver是HTML5中的新API,是个用来监视DOM变动的接口。他能监听一个DOM对象上发生的子节点删除、属性修改、文本内容修改等等。

调用过程很简单,但是有点不太寻常:你需要先给他绑回调:

var mo = new MutationObserver(callback)
로그인 후 복사

通过给MutationObserver的构造函数传入一个回调,能得到一个MutationObserver实例,这个回调就会在MutationObserver实例监听到变动时触发。

这个时候你只是给MutationObserver实例绑定好了回调,他具体监听哪个DOM、监听节点删除还是监听属性修改,还没有设置。而调用他的observer方法就可以完成这一步:

var domTarget = 你想要监听的dom节点
mo.observe(domTarget, {
   characterData: true //说明监听文本内容的修改。
})
로그인 후 복사

在nextTick中 MutationObserver的作用就如上图所示。在监听到DOM更新后,调用回调函数。

其实使用 MutationObserver的原因就是 nextTick想要一个异步API,用来在当前的同步代码执行完毕后,执行我想执行的异步回调,包括Promise和 setTimeout都是基于这个原因。其中深入还涉及到microtask等内容,暂时不理解,就不深入介绍了。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

如何实现vue2.0响应式(详细教程)

详细讲解React中的refs(详细教程)

通过JS如何实现文字间歇循环滚动效果

위 내용은 Vue의 nextTick 메소드에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 채팅 명령 및 사용 방법
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Vue 용 버튼에 기능을 추가하는 방법 Vue 용 버튼에 기능을 추가하는 방법 Apr 08, 2025 am 08:51 AM

HTML 템플릿의 버튼을 메소드에 바인딩하여 VUE 버튼에 함수를 추가 할 수 있습니다. 메소드를 정의하고 VUE 인스턴스에서 기능 로직을 작성하십시오.

Vue에서 부트 스트랩을 사용하는 방법 Vue에서 부트 스트랩을 사용하는 방법 Apr 07, 2025 pm 11:33 PM

vue.js에서 bootstrap 사용은 5 단계로 나뉩니다 : Bootstrap 설치. main.js.의 부트 스트랩 가져 오기 부트 스트랩 구성 요소를 템플릿에서 직접 사용하십시오. 선택 사항 : 사용자 정의 스타일. 선택 사항 : 플러그인을 사용하십시오.

vue.js로 JS 파일을 참조하는 방법 vue.js로 JS 파일을 참조하는 방법 Apr 07, 2025 pm 11:27 PM

vue.js에서 JS 파일을 참조하는 세 가지 방법이 있습니다. & lt; script & gt; 꼬리표;; mounted () 라이프 사이클 후크를 사용한 동적 가져 오기; Vuex State Management Library를 통해 수입.

Vue에서 시계를 사용하는 방법 Vue에서 시계를 사용하는 방법 Apr 07, 2025 pm 11:36 PM

vue.js의 시계 옵션을 사용하면 개발자가 특정 데이터의 변경 사항을들을 수 있습니다. 데이터가 변경되면 콜백 기능을 트리거하여 업데이트보기 또는 기타 작업을 수행합니다. 구성 옵션에는 즉시 콜백을 실행할지 여부와 DEEP를 지정하는 즉시 포함되며, 이는 객체 또는 어레이에 대한 변경 사항을 재귀 적으로 듣는 지 여부를 지정합니다.

Vue가 이전 페이지로 돌아 오는 방법 Vue가 이전 페이지로 돌아 오는 방법 Apr 07, 2025 pm 11:30 PM

vue.js는 이전 페이지로 돌아갈 수있는 네 가지 방법이 있습니다. $ router.go (-1) $ router.back () 사용 & lt; router-link to = & quot;/quot; Component Window.history.back () 및 메소드 선택은 장면에 따라 다릅니다.

Vue 다중 페이지 개발은 무엇을 의미합니까? Vue 다중 페이지 개발은 무엇을 의미합니까? Apr 07, 2025 pm 11:57 PM

VUE 멀티 페이지 개발은 vue.js 프레임 워크를 사용하여 응용 프로그램을 구축하는 방법입니다. 여기서 응용 프로그램은 별도의 페이지로 나뉩니다. 코드 유지 보수 : 응용 프로그램을 여러 페이지로 분할하면 코드를보다 쉽게 ​​관리하고 유지 관리 할 수 ​​있습니다. 모듈 식 : 각 페이지는 쉬운 재사용 및 교체를 위해 별도의 모듈로 사용할 수 있습니다. 간단한 라우팅 : 페이지 간의 탐색은 간단한 라우팅 구성을 통해 관리 할 수 ​​있습니다. SEO 최적화 : 각 페이지에는 자체 URL이있어 SEO가 도움이됩니다.

VUE 버전을 쿼리하는 방법 VUE 버전을 쿼리하는 방법 Apr 07, 2025 pm 11:24 PM

Vue DevTools를 사용하여 브라우저 콘솔에서 vue 탭을 보면 VUE 버전을 쿼리 할 수 ​​있습니다. npm을 사용하여 "npm list -g vue"명령을 실행하십시오. package.json 파일의 "종속성"객체에서 vue 항목을 찾으십시오. Vue Cli 프로젝트의 경우 "vue -version"명령을 실행하십시오. & lt; script & gt에서 버전 정보를 확인하십시오. vue 파일을 나타내는 html 파일의 태그.

Vue의 div로 점프하는 방법 Vue의 div로 점프하는 방법 Apr 08, 2025 am 09:18 AM

VUE에서 DIV 요소를 점프하는 두 가지 방법이 있습니다. VUE 라우터를 사용하고 라우터 링크 구성 요소를 추가하십시오. @Click 이벤트 리스너를 추가하고 이것을 호출하십시오. $ router.push () 메소드를 점프하십시오.

See all articles