I.はじめに
この段階で主流のフレームワークの 1 つとして、Vue は多くのプロジェクトでプロジェクトのフロントエンド モジュールを構築するために使用されています。この記事では、誰もが Vue をよりよく理解できるように、Vue でページをレンダリングするときに発生する仮想 DOM 比較で使用されるアルゴリズムを主に紹介します。
2.はじめに
MVVM、つまり、モデル、ビュー、ビュー モデル、ビジネス レイヤー、ビュー レイヤー、およびバインディング レイヤーの 2 つ、Vue の設計はこのアーキテクチャを指します。
<h1>{
{title}}</h1>
<script lang='ts' setup>
const title = 'this is title'
</script>
In Vue, <h1>
tags are managed by the view layer, but const title = 'this is title'
by the model layer. ビュー モデル レイヤーが行う必要があるのは、2 つのデータの同期を維持することです。ラベル データを更新するには、再レンダリングする必要があります。
レスポンシブ データ変更のレンダリングは古いvnode
存在であるため、Vue は作成された DOM 要素を最大限に再利用する必要があり、再利用の前提は新旧を比較してvnode
更新が必要なコンテンツを見つけ出し、最小化することです。交換。更新プロセス:
-
データを変更してセッターをトリガーし、Dep.notify を呼び出して、すべてのサブスクライバーに通知します Watcher;
-
render 関数を再実行して を生成します
newVnode
。 -
Execution
patch(vnode,newVnode)
、diff
アルゴリズムは、更新が必要な最終ノードを取得します。
3.差分アルゴリズム
1.差分アルゴリズムとは
差分アルゴリズムは、仮想ノードを比較し、パッチ オブジェクトを返して 2 つのノード間の差分を格納し、最後にパッチによって記録されたメッセージを使用して Dom をローカルに更新することです。
言い換えれば分かりやすい
diff の処理は、patch という関数を呼び出し、新旧のノードを比較し、比較しながら実際の DOM にパッチを適用することです。
2. 手順
-
状態が変化すると、JS オブジェクト構造によって表される DOM ツリーを再構築します。
-
新しい DOM ツリーを古い DOM ツリーと比較し、相違点を記録します (diff)。
-
記録された差分を実際の DOM に適用する (パッチ)
3.具体的な方法
基本戦略
-
同レベル比較
-
左右を中央で比較
例えば
新旧はvnode
以下の通りです。
最初のサイクル:が指している と が指しているとが指している と が指している F をそれぞれ比較し (以下の比較方法は同じです。スキップします)、それらが同じノードを持っていることを見つけてoldVnode
、それをstartIndex
直接再利用します。as 実ノード、では1 ビット前方、 では 1 ビット後方。A
endIndex
D
newVnode
startIndex
D
newVnode
endIndex
D
D
oldVnode
endIndex
newVnode
startIndex
2 番目のサイクル: A
、と比較C
しC
、同じものF
を取得しC
、ノードを再利用しC
、ポインターを移動します。
3 番目のサイクル:と比較して、再利用可能なノードA
がないことを確認し、新しいノードを作成して、1 ビット後方に移動します。B
E
F
E
newVnode
startIndex
4 サイクル: A
、と比較B
しB
、F
B と同じ値を取得し、ノード を多重化しB
、ポインターを移動します。
5 番目のサイクル:とA
を比較し、A と同じ値を取得し、ノード を再利用し、ポインターが移動した後にヘッド ポインターがテール ポインターよりも大きいことを確認し、ヘッド ポインターとテール ポインターの間にすべてのノード ( )を作成し、サイクルから飛び出します。A
F
A
oldVnode
newVnode
F
4.まとめ
-
データが変更されると、サブスクライバー ウォッチャーは patch を呼び出して実際の DOM にパッチを適用します。
-
isSameVnodeで判断、同じならpatchVnodeメソッドを呼ぶ
-
patchVnode は次のことを行います。
-
el と呼ばれる、対応する実際の dom を見つけます。
-
両方にテキスト ノードがあり、等しくない場合は、el テキスト ノードを
Vnode
テキスト ノードに設定します。 -
oldVnode
子ノードがあるのにない場合はVNode
、el 子ノードを削除します。 -
oldVnode
子ノードがない場合VNode
、VNode
子ノードが実現され、el に追加されます。 -
両方に子ノードがある場合は、updateChildren 関数を実行して子ノードを比較します。
-