>웹 프론트엔드 >View.js >Vue.$nextTick에 대해 더 깊이 이해해 보세요(원리에 대한 간략한 분석).

Vue.$nextTick에 대해 더 깊이 이해해 보세요(원리에 대한 간략한 분석).

青灯夜游
青灯夜游앞으로
2023-03-01 20:03:372122검색

이 글은 Vue에 대한 순수한 지식을 공유하고, 여러분이 모르는 Vue.nextTick을 소개하고, Vue.$nextTick의 원리에 대해 이야기하는 것이 모든 분들께 도움이 되기를 바랍니다!

Vue.$nextTick에 대해 더 깊이 이해해 보세요(원리에 대한 간략한 분석).

원칙에는 더 많은 텍스트가 포함됩니다. 인내심을 갖고 주의 깊게 음미해 보세요.

Vue의 DOM 업데이트 메커니즘

야망을 달성하기 위해 Vue를 공격적으로 사용할 때 갑자기 다음과 같은 사실을 발견하게 됩니다. 이 데이터를 변경했는데, 가져오면 왜 마지막 값인가요? (게으르기 때문에 구체적인 예를 들어주지 않겠습니다.)

이때 Vue는 다음과 같이 말할 것입니다: "Sample, here you go I don" 이해가 안 가네요. DOM이 비동기적으로 업데이트됩니다!”

간단히 말하면 Vue의 반응성은 데이터 변경 직후 DOM을 변경할 뿐만 아니라 특정 업데이트 전략에 따라 DOM도 변경합니다. 이것의 장점은 DOM에서 불필요한 작업을 방지하고 렌더링 성능을 향상시킬 수 있다는 것입니다. [관련 권장 사항: vuejs 비디오 튜토리얼, 웹 프론트 엔드 개발]

이 내용은 공식 Vue 문서에 설명되어 있습니다:

Vue가 DOM 업데이트를 비동기식으로 수행한다는 사실을 눈치채지 못했을 수도 있습니다. 데이터 변경 사항이 관찰되는 한 Vue는 대기열을 열고 동일한 이벤트 루프에서 발생하는 모든 데이터 변경 사항을 버퍼링합니다. 동일한 감시자가 여러 번 트리거되면 대기열에 한 번만 푸시됩니다. 버퍼링 중 데이터 중복 제거는 불필요한 계산 및 DOM 작업을 방지하는 데 매우 중요합니다. 그런 다음 다음 이벤트 루프 "틱"에서 Vue는 큐를 플러시하고 실제(중복 제거된) 작업을 수행합니다.

직접 말하자면 이는 실제로 JS의 이벤트 루프와 밀접하게 관련되어 있습니다. 즉, Vue는 모든 데이터 변경 사항을 먼저 렌더링할 수 없으며 동시에 이러한 변경 사항을 비동기 대기열에 넣습니다. 예를 들어 이 데이터를 세 번 수정하면 마지막 데이터만 유지됩니다. 이러한 변경 사항은 대기열 형식으로 저장될 수 있습니다. 이제 Vue가 이벤트 루프에서 DOM을 수정하는 시간은 언제입니까?

Vue에는 두 가지 옵션이 있습니다. 하나는 이 이벤트 루프가 끝날 때 DOM을 업데이트하는 것이고, 다른 하나는 이벤트 루프의 다음 라운드에 DOM 업데이트를 넣는 것입니다. z이때 You Yuxi는 가슴을 두드리며 "나에게는 두 가지 방법이 모두 있습니다!"라고 말했습니다. 그러나 이번 이벤트 루프의 최종 실행은 다음 이벤트 루프보다 훨씬 빠르기 때문에 Vue는 첫 번째 방법을 우선시합니다. . , 두 번째 메커니즘은 환경이 이를 지원하지 않는 경우에만 트리거됩니다. (??로 시작하는 링크를 보면 이벤트 루프를 이해할 수 있습니다.)

성능이 많이 향상되었지만 이벤트 루프를 한 바퀴 돌 때 코드 실행 후 문제가 발생한다는 것을 우리는 모두 알고 있습니다. 동기 실행 스택이 완료되었습니다. 비동기 큐의 내용을 실행하면 DOM을 얻는 작업이 동기식입니다! ! 데이터를 변경했음에도 불구하고 업데이트가 비동기식이며, 데이터를 얻었을 때 변경할 시간이 없었기 때문에 기사 시작 부분의 문제가 발생한다는 의미는 아닐까요?

이것. . . 이거 꼭 해야 하는데 어떻게 해야 하나요? ?

상관없습니다. Youda는 Vue.$nextTick()Vue.$nextTick()

Vue.$nextTick()

其实一句话就可以把$nextTick这个东西讲明白:就是你放在$nextTick 当中的操作不会立即执行,而是等数据更新、DOM更新完成之后再执行,这样我们拿到的肯定就是最新的了。

再准确一点来讲就是$nextTick方法将回调延迟到下次DOM更新循环之后执行。(看不懂这句人话的,可以看上面[狗头])

意思我们都懂了,那$nextTick是怎样完成这个神奇的功能的呢? 核心如下:

Vue在内部对异步队列尝试使用原生的Promise.thenMutationObserversetImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0)代替。

仔细地看这句话,你就可以发现这不就是利用 JavaScript 的这些异步回调任务队列,来实现 Vue 框架中自己的异步回调队列。这其实就是一个典型的将底层 JavaScript 执行原理应用到具体案例中的示例。

我在这里稍微总结一下:就是$nextTick

Vue.$nextTick()

🎜을 매우 신중하게 제공했습니다. 실제로 한 문장으로 $nextTick을 명확하게 설명할 수 있습니다. $nextTick에 넣은 작업은 즉시 실행되지 않고 데이터 업데이트 및 DOM 업데이트가 완료될 때까지 기다립니다. 나중에 실행하면 우리가 얻는 것이 확실히 최신이 될 것입니다. 🎜🎜더 정확하게 말하면 $nextTick 메서드는 다음 DOM 업데이트 주기까지 콜백을 지연합니다. (이 문장이 이해가 안 되신다면 위의 [개 머리]를 읽어보세요) 🎜🎜우리 모두 의미를 이해하고 있는데, $nextTick은 이 마법 같은 기능을 어떻게 수행할까요? 핵심은 다음과 같습니다. 🎜🎜🎜Vue는 내부적으로 기본 Promise.then, MutationObserversetImmediate를 사용하려고 시도합니다. 비동기 대기열 >의 경우 실행 환경에서 이를 지원하지 않으면 setTimeout(fn, 0)이 대신 사용됩니다. 🎜🎜🎜이 문장을 주의 깊게 살펴보면 이것이 단지 JavaScript의 비동기 콜백 작업 큐를 사용하여 Vue 프레임워크에서 자신만의 비동기 콜백 큐를 구현하는 것이 아니라는 것을 알 수 있습니다. 이는 실제로 기본 JavaScript 실행 원칙을 특정 사례에 적용하는 전형적인 예입니다. 🎜🎜여기에 조금 요약해 보겠습니다. $nextTick은 콜백 함수를 마이크로 작업이나 매크로 작업에 넣어 실행 순서를 지연시킵니다(요약이 너무 게으른가요?) 🎜🎜The 중요한 것은 소스 코드에서 세 가지 매개변수의 의미를 이해하는 것입니다. 🎜
  • callback: 수행하려는 작업을 이 함수에 배치할 수 있습니다. $nextTick을 한 번 실행하기 전에 콜백 함수를 비동기 대기열에 넣을 것입니다.
  • $nextTick就会把回调函数放到一个异步队列当中;
  • pending:标识,用以判断在某个事件循环中是否为第一次加入,第一次加入的时候才触发异步执行的队列挂载
  • timerFunc:用来触发执行回调函数,也就是Promise.thenMutationObserversetImmediatesetTimeout的过程

理解之后,在看整个$nextTick里面的执行过程,其实就是把一个个$nextTick中的回调函数压入到callback队列当中,然后根据事件的性质等待执行,轮到它执行的时候,就执行一下,然后去掉callback队列中相应的事件。

使用

说了这么多,怎么用它呢? 很简单很简单

mounted: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been rendered
  })
}

使用场景

  • created中获取DOM的操作需要使用它

  • 就是我们上面的例子,你如果想要获取最新值,就用它

  • 还有一些第三方插件使用过程中,使用到的情况,具体问题具体分析

参考 前端进阶面试题详细解答

补充

之前我一直搞不懂一个的问题,$nextTick既然把它传入的方法变成微任务了,那它和其它微任务的执行顺序是怎样的呢?

这简单来说就是谁先挂载Promise对象的问题,在调用$nextTick方法时就会将其闭包内部维护的执行队列挂载到Promise对象,在数据更新时Vue内部首先就会执行$nextTick方法,之后便将执行队列挂载到了Promise对象上,其实在明白JsEvent Loop模型后,将数据更新也看做一个$nextTick方法的调用,并且明白$nextTick方法会一次性执行所有推入的回调,就可以明白执行顺序的问题了

还有$nextTicknextTick区别就是nextTick多了一个context参数,用来指定上下文。但两个的本质是一样的,$nextTick是实例方法,nextTick是类的静态方法而已;实例方法的一个好处就是,自动给你绑定为调用实例的thispending: recognition; 이벤트 루프에 처음으로 조인하는지 확인하기 위해 비동기 실행을 위한 큐 마운팅은 처음 추가될 때만 트리거됩니다.

timerFunc: 실행 콜백 함수를 트리거하는 데 사용됩니다. > Promise.then 또는 MutationObserver 또는 setImmediate 또는 setTimeout

의 프로세스를 이해하신 후, $nextTick의 전체 실행 프로세스는 실제로 $nextTick의 콜백 함수를 콜백 대기열에 푸시한 다음 이벤트의 성격에 따라 실행을 기다리는 것입니다. 실행되면 실행된 후 콜백 큐에 있는 해당 이벤트가 제거됩니다.

사용

너무 많이 말했는데 어떻게 사용하나요? 매우 간단합니다rrreee

사용 시나리오

    생성됨 이를 사용하여 DOM을 가져옵니다🎜🎜🎜위의 예입니다. 최신 값을 얻으려면 사용하세요🎜🎜🎜사용되는 타사 플러그인도 있습니다. 사용 상황, 특정 문제에 대한 구체적인 분석 🎜🎜참조고급 프런트 엔드 인터뷰 질문에 대한 자세한 답변🎜🎜

    보충

    🎜이전에는 질문을 이해할 수 없었습니다. $nextTick이 수신 메서드를 마이크로 태스크로 전환했기 때문에 해당 질문과 다른 마이크로 태스크가 실행되는 순서는 무엇입니까? 🎜🎜이것은 단순히 누가 Promise 객체를 먼저 마운트하느냐의 문제입니다. $nextTick 메소드가 호출되면 클로저 내부에 유지되는 실행 대기열이 Promise 객체, 데이터가 업데이트되면 Vue는 먼저 $nextTick 메서드를 내부적으로 실행한 다음 실행 대기열을 Promise 객체는 실제로 <code>JsEvent Loop 모델을 이해한 후에는 데이터 업데이트도 $nextTick에 대한 호출로 간주됩니다. > 메소드를 사용하고 $nextTick 메소드가 푸시된 모든 콜백을 한 번에 실행한다는 것을 이해하면 실행 순서의 문제를 이해할 수 있습니다🎜🎜$nextTicknextTick차이점은 nextTick에 컨텍스트를 지정하는 추가 컨텍스트 매개변수가 있다는 것입니다. 하지만 둘의 본질은 같습니다. $nextTick은 인스턴스 메소드이고, nextTick은 클래스의 정적 메소드일 뿐이라는 점은 인스턴스 메소드의 한 가지 장점입니다. 자동으로 바인딩됩니다. 인스턴스의 this를 호출하면 됩니다. 🎜🎜 (학습 영상 공유: 🎜vuejs 입문 튜토리얼🎜, 🎜기본 프로그래밍 영상🎜)🎜

    위 내용은 Vue.$nextTick에 대해 더 깊이 이해해 보세요(원리에 대한 간략한 분석).의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제