Javascript 仮想 DOM の詳細な説明

Javascript 仮想 DOM の詳細な説明

仮想DOMとは何ですか?

仮想 DOM は、本質的には共通の JS オブジェクト (このオブジェクトの内容は、mounted._vnode に出力されます) であり、ビューのインターフェース構造を記述するために使用されます。

Vue では、各コンポーネントにレンダリング関数があり、各レンダリング関数は仮想 DOM ツリーを返します。つまり、各コンポーネントは仮想 DOM ツリーに対応します。

ここに画像の説明を挿入

vnode は、次のようなインターフェイスに何を配置するかを記述するために使用される一般的な JS オブジェクトです。

var vnode = {
  タグ: "h1",
  子供たち: [
    { タグ: undefined、テキスト: "最初の Vue アプリケーション: Hello World"}
  ]
}

上記のオブジェクトは以下を説明します。

h1というタグ名を持つノードがあり、その子ノードは「最初のVueアプリケーション: Hello World」という内容のテキストです。

なぜ仮想DOMが必要なのでしょうか?

Vue では、ビューをレンダリングすると render 関数が呼び出されます。このレンダリングは、コンポーネントが作成されたときだけでなく、ビューが依存するデータが更新されたときにも発生します。レンダリング中に実際の DOM を直接使用すると、実際の DOM の作成、更新、挿入によってパフォーマンスが大幅に低下し、レンダリング効率が大幅に低下します。

そのため、レンダリング時に、Vue は実際の DOM ではなく仮想 DOM を使用し、主にレンダリング効率の問題を解決します。

js オブジェクトと実際の dom オブジェクトの作成効率を比較します。

ここに画像の説明を挿入

結果:

ここに画像の説明を挿入

実際のDOMを作成するには多くの属性を作成する必要があります

ここに画像の説明を挿入

仮想 DOM はどのようにして実際の DOM に変換されるのでしょうか?

コンポーネント インスタンスが初めてレンダリングされるとき、まず仮想 DOM ツリーを生成し、次に仮想 DOM ツリーに基づいて実際の DOM を作成し、実際の DOM をページ内の適切な場所にマウントします。このとき、各仮想 DOM は実際の DOM に対応します。ページが 1 回だけ更新され、その後データが更新されない場合は、仮想 DOM を使用する方が実際の DOM を直接表示するよりも効率が低くなります。

コンポーネントがレスポンシブデータの変更の影響を受け、再レンダリングする必要がある場合でも、レンダリング関数を再度呼び出し、新しい仮想DOMツリーを作成し、新しいツリーを古いツリーと比較し、比較を通じて違いを見つけ、異なる部分の仮想DOMノードのみを更新します。最後に、これらの更新された仮想ノードは、対応する実際のDOMを変更します。

このようにして、実際の DOM は最小限に変更されます。

ここに画像の説明を挿入

テンプレートと仮想DOMの関係

Vue フレームワークにはコンパイル モジュールがあり、主にテンプレートをレンダリング関数に変換する役割を担っており、レンダリング関数はそれを呼び出した後に仮想 DOM を取得します。

コンパイル プロセスは 2 つのステップに分かれています。

1. テンプレート文字列を AST (抽象構文ツリー: js ツリー構造を使用して元のコードを記述します。オンライン ツール: https://astexplorer.net/) に変換します。

2. ASTをレンダリング関数に変換する

vueテンプレートは実際のDOMではなく、仮想DOMにコンパイルされます。

<div id="アプリ">
  <h1>最初の Vue アプリケーション: {{title}}</h1>
  <p>著者: {{author}}</p>
</div>

上記のテンプレートは、次の構造に似た仮想DOMにコンパイルされます。

{
  タグ: "div",
  子供たち: [
    { タグ: "h1", 子: [ { テキスト: "最初の Vue アプリケーション: Hello World" } ] },
    { タグ: "p", 子: [ { テキスト: "著者: Yuan" } ] }
  ]
}

従来のインポート方法 ( script src="...vue.js ") を使用する場合、コンポーネントが最初に読み込まれたときにコンパイル時間が発生し、これをランタイムコンパイルと呼びます。

vue-cliのデフォルト設定の場合、 npm run build build)にコンパイルが行われます。パッケージ化後はテンプレートはなく、レンダリング機能のみとなり、これをテンプレートのプリコンパイルと呼びます。

コンパイルは、パフォーマンスを非常に消費する操作です。プリコンパイルにより、実行時のパフォーマンスを効果的に向上できます。さらに、実行時にコンパイルが不要になるため、vue-cli はパッケージ化時に vue のコンパイル モジュールを除外して、パッケージ サイズを削減します。

パッケージ化時にコンパイル モジュールを含める必要があるかどうかは、vue.config.js のruntimeCompiler: true によって制御されます。デフォルト値は false で、含まれないことを意味します。この設定を変更することは推奨されません

テンプレートが存在するのは、開発者がインターフェース コードを書きやすくするためだけです。

最終的にVueが実行される際に必要となるのはテンプレートではなくレンダリング関数です。そのため、テンプレート内の各種構文は仮想DOM内には存在せず、すべて仮想DOMの構成になります。

vue-cli では、テンプレートとレンダリングの両方が存在する場合、パッケージ化プロセスにより、テンプレートの事前コンパイルによってレンダリングが生成され、元のレンダリング関数が上書きされます。

Vue では、テンプレートとレンダリングの両方が同時に存在する場合、レンダリングが優先されます。

仮想DOMツリーは最終的に実際のDOMツリーに生成される。

ここに画像の説明を挿入

Vue は次のロジックを通じて vnode ツリーを生成します。

ここに画像の説明を挿入

注意: 仮想ノードツリーは単一ルートである必要があります

注射

ここに画像の説明を挿入

Vue は Vue インスタンスに次の構成を挿入します。

  • data : インターフェースに関連するデータ
  • computed : 既存のデータから計算されたデータ。詳細は後ほど説明します。
  • methods : 方法

Vueインスタンスのメンバーはテンプレートで使用できます

名前の競合を防ぐため。 data 内のデータは vue にプロキシされるため、記述したデータ名が vue 内の属性と競合すると、vue 内の属性が上書きされてしまうため、vue は自身の属性メンバー名の前に または を追加します。 または _ で追加されている場合、 または で追加されている場合、 で追加されている場合は、使用できることを意味します。 _ で追加された場合は、vue 自体が使用するメソッドまたは属性であり、呼び出す必要はありません。

マウント

生成された実際のDOMツリーを特定の要素の位置に配置することをマウントと呼びます。

取り付け方法:

1. el:"css selector" で設定する

2. vueインスタンス.$mount("cssセレクタ")を介して設定します。

プロセスを完了する

  • インスタンスが作成されます: new Vue()
  • 注入が完了した後にのみ応答性が得られ、データの変更を監視できるようになります。
  • 仮想DOMツリーをコンパイルして生成します。まずレンダリング関数を見つけ、レンダリング関数がない場合はそれを生成するテンプレートを見つけ、最後にレンダリングを実行して仮想DOMツリーを生成します。
  • マウント完了: ページが表示されます

ここに画像の説明を挿入

要約する

この記事はこれで終わりです。皆さんのお役に立てれば幸いです。また、123WORDPRESS.COM のその他のコンテンツにも注目していただければ幸いです。

以下もご興味があるかもしれません:
  • Vue 仮想 Dom から実際の Dom への変換
  • Vueにおける仮想DOMの理解のまとめ
  • Vueソースコード解析における仮想DOMの詳しい説明
  • Vue 仮想 DOM クイックスタート
  • Reactの仮想DOMとdiffアルゴリズムの詳細な説明
  • Vue仮想DOMの原理
  • Vueは仮想DOMを使用してビューをレンダリングします

<<:  RGBAアルファ透明度変換計算表

>>:  MySQL 接続制御プラグインの紹介

推薦する

Vue は Axios リクエスト フロントエンドのクロスドメイン問題をどのように解決するのか

目次序文1. クロスドメインの問題はなぜ発生するのでしょうか? 2. 解決策クロスオリジンリソース共...

docker version es、milvus、minio 起動コマンドの詳細な説明

1. es起動コマンド: docker run -itd -e TAKE_FILE_OWNERSHI...

MySql ストアド プロシージャ パラメータの初歩的な使用法の詳細な説明

パラメータでのストアドプロシージャの使用IN パラメータは、プロシージャに情報を渡すためにのみ使用さ...

Linux システムで Vim を使用してリモート ファイルを読み書きするコマンドの詳細な説明

vim の動作モードを設定する (一時的) :set (モード情報) :set nu — 行番号を表...

問題におけるJS演算子の調査

問題は、誰もが「メモリ リーク」について知っていることです。一般的なシナリオはいくつかあります。クロ...

一般的な Dockerfile コマンドの使用方法の紹介

目次01 CM 02 エントリーポイント03 ワークディレクトリ04 環境05 ユーザー06巻07 ...

CentOS で RPM を使用して MySQL 5.6 をインストールするチュートリアル

これまでのプロジェクトはすべて Windows システム環境にデプロイされていました。今回は Lin...

MySQL の異なるテーブル間でフィールドをコピーする

場合によっては、フィールドから別の新しいフィールドにデータの列全体をコピーする必要があります。これは...

Vue3 でタイマーコンポーネントをカプセル化する方法

背景一部のショッピング モールの Web ページで商品の詳細を開くと、購入数量を選択するためのカウン...

HTML(divレイヤー)を介してFLASHにリンクを追加するための実装コード

今日、クライアントが広告を掲載したいのですが、提供された素材は Flash です。私たちはあまり気に...

Ubuntu仮想マシンでシリアル通信にcutecomを使用する方法

Ubuntu仮想マシンでのシリアル通信にcutecomを使用する1. cutecomをインストールす...

Ubuntu Server でのワイヤレス ネットワーク カードの詳細な設定

1. ワイヤレス ネットワーク カードを挿入し、コマンドiwconfigを使用してワイヤレス ネット...

ウェブサイトにファビコンを追加するためのヒント: URLの前の小さなアイコン

いわゆるファビコンは、Favorites Icon の略で、中国語ではウェブサイトアバターと呼ばれて...

SQL IDENTITY_INSERT ケーススタディ

一般的に、データ テーブル内の列を ID 列として設定すると、ID 列の表示値を手動で ID 列に挿...