ホームページ >ウェブフロントエンド >Vue.js >Vue.$nextTick をより深く理解できるようにします (原理の簡単な分析)

Vue.$nextTick をより深く理解できるようにします (原理の簡単な分析)

青灯夜游
青灯夜游転載
2023-03-01 20:03:372124ブラウズ

この記事では、Vue の純粋な情報を共有し、あまり知られていない Vue.nextTick の紹介と、Vue.$nextTick の原理について説明します。

Vue.$nextTick をより深く理解できるようにします (原理の簡単な分析)

原則的なものにはさらに多くの単語が含まれます。辛抱強くじっくり味わってください。

Vue の DOM 更新メカニズム

目標を達成するために Vue を積極的に使用していると、突然、このデータは明らかに変更しましたが、取得したときにはそれが最後の値であることに気づきます (私は怠け者です。具体的な例はありませんか?)

このとき、Vue は次のように言います: 「小さい、あなたはこれを理解していません。私の DOM は非同期で更新されます!!!」

簡単に言うと、Vue の応答性は DOM が更新されることを意味するものではありません。データ変更直後に変更されますが、特定の戦略に従って DOM が更新されます。この利点は、DOM に対する不必要な操作を回避し、レンダリングのパフォーマンスを向上できることです。 [関連する推奨事項: vuejs ビデオ チュートリアル Web フロントエンド開発 ]

については、Vue の公式ドキュメントで説明されています:

おそらくまだ気づいていないかもしれませんが、Vue は DOM 更新を非同期的に実行します。データ変更が観察される限り、Vue はキューを開き、同じイベント ループ内で発生するすべてのデータ変更をバッファーに入れます。同じウォッチャーが複数回トリガーされた場合、キューにプッシュされるのは 1 回だけです。バッファリング中のこの重複排除は、不必要な計算や DOM 操作を回避するために非常に重要です。次に、次のイベント ループ「ティック」で、Vue はキューをフラッシュし、実際の (重複排除された) 作業を実行します。

率直に言うと、これは実際には JS のイベント ループと密接に関連しています。つまり、Vue はすべてのデータ変更をレンダリングすることはできません。最初にこれらの変更を非同期キューに入れます。また、キュー内の操作も重複排除されます。たとえば、データを 3 回変更した場合、最後のデータのみが保持されます。これらの変更はキューの形式で保存できますが、ここで問題は、イベント ループのどの時点で Vue が DOM を変更するかということです。

Vue には 2 つのオプションがあります。1 つはこのイベント ループの最後で DOM を更新することで、もう 1 つは DOM の更新をイベント ループの次のラウンドに入れることです。このとき、You Yuxi は胸をなでて、「私には両方の方法があります!」と言いました。しかし、このラウンドのイベント ループの最終実行は次のラウンドのイベント ループよりもはるかに高速であるため、Vue は最初の方法を優先します。 2 番目のメカニズムは、環境がサポートしていない場合にのみトリガーされます。 (?? で始まるリンクはイベント ループを理解するのに役立ちます)

パフォーマンスは大幅に改善されましたが、この時点で問題が発生します。イベント ループのラウンドでは、同期実行スタックが完了すると、非同期キューの内容が実行されるため、DOM を取得する操作は同期です。 !データを変更したものの、その更新は非同期であり、データを取得した時点では変更する時間がないため、記事冒頭の問題が発生するということではないでしょうか。 ######これ。 。 。どうしてもこれをしなければならないのですが、どうすればよいでしょうか? ?

それは問題ではありません。Youda は非常に思慮深く私たちに

Vue.$nextTick()

Vue.$nextTick()

## を提供してくれました。 #実際、$nextTick

は一文で明確に説明できます。

$nextTick に入力した操作はすぐには実行されず、データの更新と DOM を待ちます。更新が完了してから実行すると、確実に最新のものが取得されます。 より正確には、$nextTick

メソッドは、次の DOM 更新サイクルまでコールバックを遅らせます。 (この文が理解できない場合は、上の [犬の頭] を読んでください)

の意味は誰もが理解していますが、$nextTick

はどのようにしてこの魔法の機能を実現するのでしょうか?コアは次のとおりです:

Vue
内部的には、ネイティブの

Promise.thenMutationObserver、および setImmediate を使用しようとします。非同期キュー 、実行環境がサポートしていない場合は、代わりに setTimeout(fn, 0) が使用されます。 この文を注意深く見てみると、これは JavaScript の非同期コールバック タスク キューを使用して、Vue フレームワークに独自の非同期コールバック キューを実装しているだけではないことがわかります。これは、実際には、基礎となる JavaScript 実行原則を特定のケースに適用する典型的な例です。

ここで少し要約してみましょう:

$nextTick

コールバック関数をマイクロタスクまたはマクロタスクに入れて、その実行順序を遅らせます; (要約も遅延しますか?)

ソース コード内の 3 つのパラメーターの意味を理解することが重要です:

  • callback: 実行したい操作をこの関数に入れることができます。$nextTick を一度実行しないと、コールバック関数は非同期キューに入れられます。
  • pending: イベント ループへの参加が初めてであるかどうかを判断するために使用される ID。キュー マウントの非同期実行は、初めて追加された場合にのみトリガーされます。
  • timerFunc: usedコールバック関数の実行をトリガーします。つまり、Promise.then または MutationObserver または setImmediate または setTimeout
##プロセスを理解した後、

$nextTick の実行プロセス全体を見ると、実際には $nextTick のコールバック関数を 1 つずつコールバック キューにプッシュすることになります。その後、イベントの性質に従って順番が来るまで実行を待ちます。実行する場合は、それを実行してから、コールバック キュー内の対応するイベントを削除します。

使用方法

ここまで述べましたが、どのように使用するのでしょうか?非常に単純、非常に単純です

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

使用シナリオ

  • 作成された DOM を取得する操作には、それを使用する必要があります

  • は上記の例です。最新の値を取得したい場合は、それを使用してください。

  • 使用プロセス中に使用されるサードパーティのプラグインもいくつかあり、特定の

  • #参考
フロントエンドの高度なインタビューの質問に対する詳細な回答

補足

質問を理解する前に実行できませんでした。

$nextTick

渡されたメソッドはマイクロタスクになっているのですが、他のマイクロタスクとの実行順序はどうなるのでしょうか? これは単に、誰が

Promise

オブジェクトを最初にマウントするかという問題です。$nextTick メソッドが呼び出されると、そのクロージャ内に保持されている実行キューがマウントされます。 Promise オブジェクトにロードされた Vue は、データが更新されると、まず $nextTick メソッドを内部で実行し、次に実行キューを ## にマウントします。 #お約束実際、オブジェクト上では、JsEvent Loop モデルを理解した後、データ更新も $nextTick# の呼び出しとみなされます。 ## メソッドと $nextTick メソッドはプッシュされたすべてのコールバックを一度に実行するため、実行順序 の問題と $nextTick の違いを理解できます。および

nextTick

つまり、nextTick には、コンテキストを指定する追加のコンテキスト パラメーターがあります。しかし、この 2 つの本質は同じです。$nextTick はインスタンス メソッドであり、nextTick はクラスの単なる静的メソッドです。インスタンス メソッドの利点の 1 つは、次のとおりです。呼び出し元のインスタンスに自動的にバインドされます。これは this だけです。 (学習ビデオ共有: vuejs 入門チュートリアル

基本プログラミング ビデオ

)

以上がVue.$nextTick をより深く理解できるようにします (原理の簡単な分析)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。