2023 フロントエンド インタビュー ランディング マニュアル - VUE パート

目次

Vue の基礎

Vue インスタンスが作成されると、Vue はデータ内のプロパティをトラバースし、Object.defineProperty (vue3.0 はプロキシを使用) を使用してそれらを getter/setter に変換し、関連する依存関係を内部的に追跡し、プロパティがアクセスおよび変更されたときに変更を通知します。各コンポーネント インスタンスには、対応するウォッチャー プログラム インスタンスがあり、
コンポーネント関係のセッターが呼び出されると、ウォッチャーに再計算するように通知します。更新します。
ここに画像の説明を挿入

双方向データバインディングの原則

Vue.js はパブリッシャー/サブスクライバー モードと組み合わせたデータ ハイジャックを採用し、Object.defineProperty() を介して各プロパティのセッターとゲッターをハイジャックし、データが変更されたときにサブスクライバーにメッセージをパブリッシュし、対応するモニタリング コールバックをトリガーします。主に以下のステップに分かれています。

  1. 監視が必要なデータ オブジェクトは、サブプロパティ オブジェクトのプロパティを含めて再帰的にトラバースされ、setter と getter が追加されます. この場合、このオブジェクトに値を割り当てると、setter がトリガーされ、次にデータが変更されます監視可能

  2. compile はテンプレート命令を解析し、テンプレート内の変数をデータに置き換え、レンダリングされたページ ビューを初期化し、各命令に対応するノードを更新関数でバインドし、データをリッスンするサブスクライバーを追加します。データが変更されると、通知と更新ビュー

  3. Watcher サブスクライバーは、Observer と Compile の間の通信ブリッジです. 主に行うことは: ① 自分自身をインスタンス化するときにプロパティ サブスクライバー (dep) に自分自身を追加すること ② update() メソッドを持っている必要があること ③ プロパティが dep を変更するのを待つこと. notice() によって通知されると、独自の update() メソッドを呼び出して、コンパイルでバインドされたコールバックをトリガーすることができ、成功します。

  4. MVVM は、データ バインディングの入り口として、Observer、Compile、および Watcher を統合し、Observer を介して独自のモデル データの変更を監視し、Compile を介してテンプレート命令を解析およびコンパイルし、最後に Watcher を使用して Observer と Compile 間の通信ブリッジを構築し、データの変更を実現します。 > 更新を表示; インタラクティブな変更 (入力) を表示 -> データ モデル変更の双方向バインディング効果。
    ここに画像の説明を挿入

MVVM、MVC、MVP の違い

MVC、MVP、および MVVM は、主にコード構造を整理し、関心を分離することによって開発効率を最適化する 3 つの一般的なソフトウェア アーキテクチャ設計パターンです。

シングルページ アプリケーションを開発する場合、多くの場合、ルーティング ページはスクリプト ファイルに対応し、すべてのページ ロジックはスクリプト ファイル内にあります。ページのレンダリング、データの取得、ユーザー イベントへの応答、すべてのアプリケーション ロジックが混在しているため、単純なプロジェクトを開発する場合は問題が発生しない可能性があります。プロジェクトが複雑になると、ファイル全体が次のようになります。これは、プロジェクトの開発とその後のプロジェクトの保守に非常に有害です。

  1. MVC

MVC は、モデル、ビュー、およびコントローラーを分離することによってコード構造を編成します。このうち、View はページの表示ロジックを担当し、Model はページの業務データの格納と対応するデータの操作を担当します。View と Model は Observer パターンを適用し、Model レイヤーが変更されると、関連する View レイヤーにページを更新するよう通知します。

コントローラ レイヤは、ビュー レイヤとモデル レイヤの間のリンクです. これは主に、ユーザーとアプリケーション間の応答操作を担当します. ユーザーがページを操作すると、コントローラのイベント トリガーが機能し始めます. Model レイヤー、Model が完成した変更、Model レイヤーは View レイヤーに更新を通知します。

ここに画像の説明を挿入

  1. MVVM

ModelMVVM は、Viewに分けられますViewModel

Model はデータ モデルを表し、データとビジネス ロジックは Model レイヤーで定義され、View は UI ビューを表し、データの表示を担当します。

ViewModel は、モデル内のデータの変更を監視し、ビューの更新を制御し、ユーザー インタラクション操作を処理します。

モデルとビューは直接関連していませんが、ビューモデルを介して接続されており、モデルとビューモデルの間には双方向のデータ バインディング関係があります。したがって、モデル内のデータが変更されると、ビュー レイヤーの更新がトリガーされ、ユーザーの操作によってビュー内で変更されたデータもモデル内で同期されます。

このモードでは、モデル データとビュー データの自動同期が実現されるため、開発者は DOM 自体を操作するのではなく、データのメンテナンス操作のみに集中する必要があります。

ここに画像の説明を挿入

  1. MVP

MVP パターンと MVC の唯一の違いは、プレゼンターとコントローラーです。MVC パターンのオブザーバー パターンを使用して、モデル レイヤーのデータが変更されたときにビュー レイヤーの更新を実現します。このように View レイヤーと Model レイヤーが結合されているため、プロジェクトのロジックが複雑になると、コードの混乱やコードの再利用性に問題が生じる可能性があります。MVP パターンは、Presenter を使用して View レイヤーと Model レイヤーの分離を実現します。MVC の Controller は Model のインターフェースしか知らないため、View レイヤーの更新を制御する方法がありません.MVP モードでは、View レイヤーのインターフェースが Presenter に公開されるため、Model とView の変更は Presenter で結合できるため、View と Model の同期更新が実現されます。このように、View と Model の分離が実現され、Presenter にはその他の応答ロジックも含まれています。

スロットとは?効果は何ですか?原則は何ですか?

スロット (スロットとも呼ばれます) は、Vue のコンテンツ配信メカニズムです. コンポーネント内のテンプレート エンジンは、スロット要素を、コンテンツの実行と配信のアウトレットとして使用します。スロット slot は、子コンポーネントのテンプレート ラベル要素であり、このラベル要素を表示するかどうか、およびどのように表示するかは、親コンポーネントによって決定されます。スロットには、デフォルト スロット、名前付きスロット、スコープ スロットの 3 種類があります。

デフォルト スロット: 匿名スロットとも呼ばれます。スロットで name 属性値が指定されていない場合、スロットはデフォルトで表示され、コンポーネントには匿名スロットが 1 つしかありません。

名前付きスロット: 特定の名前を持つスロット, つまり, name 属性を持つスロット. コンポーネントは複数の名前付きスロットを持つことができます.

スコープ スロット: デフォルト スロット、名前付きスロットのバリアントであり、匿名スロットまたは名前付きスロットにすることができます。このスロットの違いは、サブコンポーネントがスコープ スロットをレンダリングするとき、サブコンポーネント コンポーネント内のデータが親コンポーネントに渡され、親コンポーネントに渡されることです。コンポーネントは、子コンポーネントから渡されたデータに基づいてスロットをレンダリングする方法を決定します。

実装原理: 子コンポーネント vm がインスタンス化されると、親コンポーネントによって渡されたスロット タグの内容が取得され、vm.$slot に格納されます。デフォルト スロットは vm.$slot.default であり、名前付きスロットは vm です。 .$slot .xxx, where xxx is the name of the slot. コンポーネントがレンダリング関数を実行すると、スロット ラベルに遭遇し、それを $slot のコンテンツに置き換えます。この時点で、データをスロットに渡すことができます。データがある場合、そのスロットは Scoped スロットと呼ぶことができます。

$nextTick の原理と機能

Vue の nextTick の本質は、JavaScript 実行原理 EventLoop の適用です。

nextTick のコアは、Promise、MutationObserver、setImmediate、setTimeout などのネイティブ JavaScript メソッドを使用して、対応するマイクロ/マクロ タスクの実装をシミュレートすることです.本質は、これらの JavaScript の非同期コールバック タスク キューを使用して、独自の非同期コールバック キューを実現することですVue フレームワークで。

nextTick は Vue 内の非同期キューの呼び出しメソッドであるだけでなく、開発者が実際のプロジェクトでこのメソッドを使用して、実際のアプリケーションでの DOM 更新データのタイミングの後続の論理処理を満たすこともできます. nextTick は、基になる JavaScript 実行の典型的なアプリケーションです具体的な原則 事例の例、非同期更新キューメカニズムを導入する理由:

同期更新の場合、1 つまたは複数の属性を複数回割り当てると、UI/DOM レンダリングが頻繁にトリガーされ、無駄なレンダリングを減らすことができます。

同時に、VirtualDOM の導入により、状態が変化するたびに状態変化信号がコンポーネントに送信され、コンポーネントは VirtualDOM を使用して、更新が必要な特定の DOM ノードを計算し、DOM を更新します。 . 各状態の更新後 レンダリング プロセスはより多くの計算を必要とし、この無用な作業はより多くのパフォーマンスを浪費するため、非同期レンダリングがより重要になります。

Vue はデータ駆動型ビューの考え方を採用していますが、場合によっては DOM を操作する必要があります。DOM1 のデータが変更され、DOM2 が DOM1 からデータを取得する必要がある場合、DOM2 のビューが更新されていないことがわかり、nextTick を使用する必要がある場合があります。

Vue の DOM 操作は非同期であるため、上記の場合、$nextTick にデータを取得する DOM2 の操作を記述する必要があります。

ここに画像の説明を挿入

したがって、nextTick は次の場合に使用されます。

データが変更された後に操作が実行され、この操作がデータの変更に伴って変化する DOM 構造を使用する必要がある場合、この操作は nextTick() のコールバック関数内にある必要があります。

vue ライフサイクルでは、DOM 操作が created() フックで実行される場合、nextTick() のコールバック関数にも配置する必要があります。

created() フック関数では、ページの DOM がレンダリングされておらず、現時点で DOM を操作する方法がないため、現時点で DOM を操作する場合は、次のコードを配置する必要があります。 nextTick() のコールバック関数での操作。

Vueシングルページアプリとマルチページアプリの違い

コンセプト:

SPA シングル ページ アプリケーション (SinglePage Web アプリケーション) は、メイン ページが 1 つしかないアプリケーションを指し、最初に js、css、およびその他の関連リソースを一度だけロードする必要があります。すべてのコンテンツはメイン ページに含まれ、各機能モジュールはコンポーネント化されています。シングルページ アプリケーションのジャンプは、関連するコンポーネントを切り替えて、ローカル リソースのみを更新することです。

MPA マルチページ アプリケーション (MultiPage Application) は、複数の独立したページを持つアプリケーションを指し、各ページは js、css、およびその他の関連リソースを繰り返しロードする必要があります。複数ページのアプリケーション ジャンプには、ページ全体のリソースの更新が必要です。

違い:
ここに画像の説明を挿入

Vue にカプセル化された配列メソッドとは何ですか?また、それらはどのようにページ更新を実装しますか?

Vue では Object.defineProperty を使用してレスポンシブ処理用のデータをインターセプトしますが、このメソッドでは配列の内部変更、配列の長さの変更、配列のインターセプトの変更などを監視できないため、これらの操作を行う必要があります。ハッキングされて、Vue の変更を監視できるようになります。

ここに画像の説明を挿入

では、Vue はこれらの配列メソッドのリアルタイム更新をどのように実現するのでしょうか? 以下は、Vue でのこれらのメソッドのカプセル化です:
ここに画像の説明を挿入

簡単に言えば, 配列内のネイティブメソッドが書き直されます. まず, 配列の Observer オブジェクトである ob を取得します. 新しい値がある場合は、observeArray を呼び出して新しい値の変化を観察し続けます.つまり、target_proto_== arrayMethods を介して配列インスタンスの型を変更します)、手動で notify を呼び出してレンダリング ウォッチャーに通知し、更新を実行します。

Vue データのプロパティの値が変更された後、ビューはすぐに同期的に再レン​​ダリングされますか?

再レンダリングは、即時かつ同期的に実行されるわけではありません。Vue の応答性の実装は、データが変更された直後に DOM を変更するのではなく、特定の戦略に従って DOM を更新することです。Vue は、DOM の更新時に非同期で実行されます。データの変更が検出される限り、Vue はキューを開き、同じイベント ループで発生するすべてのデータ変更をバッファリングします。

同じウォッチャーが複数回トリガーされた場合、キューにプッシュされるのは 1 回だけです。バッファリング中のこの重複排除は、不要な計算や DOM 操作を避けるために非常に重要です。次に、次のイベント ループ ティックで、Vue はキューをフラッシュし、実際の

(重複排除された) 作業。

mixinと extends のカバレッジロジックを簡単に説明してください

  1. mixin 和 extends

コンポーネントのマージと展開には mixin と extends の両方が使用され、どちらも mergeOptions メソッドによってマージされます。

mixin は mixin オブジェクトの配列を受け入れます。ここで mixin オブジェクトは通常のインスタンス オブジェクトのようなインスタンス オプションを含むことができ、これらのオプションは最終的なオプションにマージされます。Mixin フックは、渡された順序で順次呼び出され、コンポーネント自体のフックが呼び出される前に呼び出されます。

extends は主に、オブジェクトまたはコンストラクターを受け取り、単一ファイル コンポーネントを拡張するのに便利です。

ここに画像の説明を挿入

  1. mergeOptions の実行手順

正規化オプション ( normalizeProps 、 normalizelnject 、 normalizeDirectives )

マージされていないオプションを判断する
ここに画像の説明を挿入

子コンポーネントは親コンポーネントのデータを直接変更できますか?

子コンポーネントは、親コンポーネントのデータを直接変更できません。これは主に、親コンポーネントと子コンポーネントの間の一方向のデータ フローを維持するために行われます。親コンポーネントが更新されるたびに、子コンポーネントのすべての props が最新の値で更新されます。これが行われると、Vue はブラウザのコンソールに警告を発行します。
子コンポーネントは、親コンポーネントのデータを直接変更できません。これは主に、
親コンポーネントと子コンポーネントの間の一方向のデータ フローを維持するために行われます。親コンポーネントが更新されるたびに、子コンポーネントのすべての props が最新の値で更新されます。これが行われると、Vue はブラウザのコンソールに警告を発行します。
Vue は一方向のデータ フローを提唱しています。つまり、親 props への更新は子コンポーネントに流れますが、逆方向には流れません。これは、親コンポーネントの状態が誤って変更され、アプリケーションのデータ フローがわかりにくくなり、データ フローに混乱が生じるのを防ぐためです。一方向のデータ フローが壊れていると、アプリケーションが複雑な場合、デバッグのコストが非常に高くなります。

$emit を介してディスパッチできるカスタム イベントは 1 つだけであり、親コンポーネントがそれを受け取った後、親コンポーネントによって変更されます。

React と Vue の理解、類似点と相違点

類似点:

  • コア ライブラリに集中し、ルーティングやグローバル ステート管理などの他の機能は関連ライブラリに任せます。

  • どちらも、ベスト プラクティスに従って設定されたプロジェクト テンプレートを取得できる独自のビルド ツールを備えており、どちらも仮想 DOM (仮想 DOM) を使用して再描画のパフォーマンスを向上させています。

  • すべてに小道具の概念があり、コンポーネント間のデータ転送を可能にします。

  • いずれもコンポーネント化されたアプリケーションを奨励し、アプリケーションを明確な機能を持つモジュールに分割して再利用性を向上させます。

違い:

  1. データ フロー
    Vue はデフォルトで双方向のデータ バインディングをサポートしていますが、React は常に一方向のデータ フローを提唱してきました。

  2. Virtual DOM
    Vue2.x は「Virtual DOM」の導入を開始し、この点で React との違いを排除しましたが、特定の詳細にはまだ独自の特徴があります。
    Vue は、コンポーネント ツリー全体を再レンダリングすることなく、レンダリング プロセス中に各コンポーネントの依存関係を追跡するため、Virtual DOM の違いをより速く計算できると主張しています。

React の場合、アプリケーションの状態が変更されるたびに、すべての子コンポーネントが再レンダリングされます。もちろん、これは PureComponent/shouldComponentUpdate ライフサイクル メソッドで制御できますが、Vue はこれをデフォルトの最適化として扱います。

  1. コンポーネント化

React と Vue の最大の違いは、テンプレートの作成です。

Vue では、通常の HTML に似たテンプレートを作成することをお勧めします。これは標準の HTML 要素に非常に近い形で記述されていますが、いくつかの属性が追加されています。

React では、すべてのテンプレートを一般的な JavaScript 構文拡張である JSX で記述することをお勧めします。

具体的には、React の render 関数はクロージャー機能をサポートしているため、インポートされたコンポーネントを render で直接呼び出すことができます。しかし Vue では、テンプレートで使用されているデータをトランジットのためにこれに掛ける必要があるため、コンポーネントをインポートした後、再度コンポーネントで宣言する必要があります。

  1. データ変更の監視の実装原則は異なります

Vue は getter/setter といくつかの関数のハイジャックによってデータの変更を正確に知ることができ、特別な最適化を行わなくても良好なパフォーマンスを実現できます. React はデフォルトで参照を比較します. 最適化されていない場合 (
PureComponent
/shouldComponentUpdate), 不要な vDOM の大量の再生成が発生する可能性があります.レンダリングします。これは、Vue が可変データを使用するのに対し、React は不変データに重点​​を置いているためです。

  1. HOC

React は高次コンポーネント (HOC) を介して拡張できますが、Vue は mixin を介して拡張する必要があります。

高階コンポーネントは高階関数であり、React コンポーネント自体は純粋な関数であるため、高階関数は React にとって簡単です。反対に、Vue.js は HTML テンプレートを使用してビュー コンポーネントを作成しますが、現時点ではテンプレートを効率的にコンパイルできないため、Vue は HOC を使用して実装することはできません。

  1. ビルドツール

どちらにも独自のビルド ツールがあります:
React ==> Create React APP
Vue ==> vue-cli

  1. クロスプラットフォーム

React ==> React Native
Vue ==> Weex

ビューの利点

  • 軽量フレームワーク: ビュー レイヤーのみに焦点を当てます。これはデータを構築するビューのセットであり、サイズはわずか数十 kb です。
  • 習得しやすい:中国語の開発、中国語の文書、言語の障壁がなく、理解しやすく、習得しやすい。
  • 双方向データ バインディング: angular の特性を保持し、データ操作がより簡単になります。
  • コンポーネント化: 反応の利点を保持し、html のカプセル化と再利用を実現し、単一ページ アプリケーションの構築に独自の利点があります。
  • ビュー、データ、および構造の分離: ロジック コードを変更せずにデータの変更を容易にし、データを操作するだけで関連する操作を完了することができます。
  • 仮想 DOM: DOM 操作は非常にパフォーマンス集約型であり、ネイティブ DOM 操作ノードを使用しなくなり、DOM 操作が大幅に解放されますが、特定の操作は依然として DOM ですが、別の方法で行われます。
  • 実行速度が速い:reactに比べて仮想DOMも動作するので、性能面ではvueのほうが有利です。

アセットと静的の違い

同じ点: assets と static はどちらも静的リソース ファイルを格納します。プロジェクトで必要なリソースファイルの画像、フォントアイコン、スタイルファイルなどをこの2つのファイルの下に配置できる点は同じです

The difference: The static resource files stored in assets will be packaged and upload when the project is packaged, つまり, when npm run build is run. いわゆる単純なパッケージングは​​、圧縮されたボリュームとコードのフォーマットとして理解できます。圧縮された静的リソース ファイルは最終的に静的ファイルに配置され、index.html と共にサーバーにアップロードされます。static に配置された静的リソース ファイルは、パッケージ化、圧縮、フォーマットなどのプロセスを経ずに、直接パッケージ化されたディレクトリに入り、サーバーに直接アップロードされます。圧縮を避けて直接アップロードするため、パッケージ化する際の効率はある程度向上しますが、静的なリソースファイルは圧縮せずに他の操作を行うため、アセット内のパッケージ化されたファイルよりもファイルサイズが大きくなります。サーバーでより多くのスペースを占有します。

提案: プロジェクトのテンプレートに必要なすべてのスタイル ファイルと js ファイルをアセットに配置し、パッケージ化のプロセスを実行できます。音量を下げます。プロジェクトで導入されたサードパーティ リソース ファイル (iconfoont.css など) は、静的に配置できます。これらのインポートされたサードパーティ ファイルは処理されており、処理する必要がなくなったため、直接アップロードできます。

削除と Vue.delete 削除配列の違い

削除された要素のみが空/未定義になり、他の要素のキー値は変更されません。

Vue.delete は配列を直接削除し、配列のキー値を変更します。

Vue テンプレートのコンパイルの原則

vue のテンプレート テンプレートはブラウザーで解析およびレンダリングできません。これはブラウザーの標準ではなく、正しい HTML 構文でもないため、テンプレートを JavaScript 関数に変換する必要があるため、ブラウザーがこの関数を実行してレンダリングできるようにするためです。対応する HTML 要素によってビューを実行できます。この変換プロセスはテンプレート コンパイルと呼ばれます。テンプレートのコンパイルは、パース解析、最適化の最適化、生成の生成、最後に実行可能な関数 render の生成の 3 つの段階に分けられます。

解析段階: 多数の正規表現を使用してテンプレート文字列を解析し、ラベル、命令、属性などを抽象構文木 AST に変換します。

最適化段階: AST をトラバースし、いくつかの静的ノードを見つけてマークします。これにより、ページが再レンダリングされるときに、差分比較を行うときにこれらの静的ノードを直接スキップでき、実行時のパフォーマンスを最適化できます。

生成フェーズ: 最終的な AST をレンダリング関数文字列に変換します。

Vue 初期化ページの点滅の問題

vue を使って開発する場合、vue の初期化前に div が vue の制御下にないため、
記述したコードが解析される前にぼやけた現象が発生しやすくなります 。通常の状況ではこの時間は非常に短いですが、それでもこの問題を解決する必要があります。
最初: 次のコードを css に追加します。
ここに画像の説明を挿入

問題が完全に解決しない場合は、ルート要素 :style="{display: 'block'}" に style="display: none;" を追加します。

MVVMの長所と短所?

アドバンテージ:

ビューとモデルを分離して、コードの結合を減らし、ビューまたはロジックの再利用性を向上させる: たとえば、ビューはモデルとは独立して変更および修正でき、ビューモデルは別の「ビュー」にバインドできます。変更されず、モデルが変更された場合、ビューも変更されないままにすることができます。ViewModel にいくつかのビュー ロジックを配置し、多くのビューでこのビュー ロジックを再利用して、テスト容易性を向上させることができます。ViewModel の存在は、開発者がテスト コードをより適切に作成するのに役立ちます。

DOM の自動更新: 双方向バインディングを使用すると、データが更新された後にビューが自動的に更新されるため、開発者は煩雑な手動の DOM から解放されます。

欠点:

バグのデバッグは困難です。双方向バインディング モードであるため、インターフェース例外が発生した場合、ビュー コードにバグがあるか、モデル コードに問題がある可能性があります。データバインディングにより、ある場所のバグを他の場所にすばやく転送できるため、元の問題を簡単に見つけることができなくなります。また、データバインディングの宣言はViewのテンプレートに命令的に書かれています. これらの内容は中断できません. デバッグの大きなモジュールでは、モデルも非常に大きくなります, 使用すると便利で非常に便利ですが. . データの一貫性を確保しやすい. 当時は長時間保持されており、メモリが解放されていなかったため、メモリ消費量が増加していました.

大規模なグラフィックス アプリケーションの場合、多くのビュー ステートがあり、ViewModel の構築と維持のコストは比較的高くなります。

v-if と v-for では、どちらの優先順位が高いですか? それらが同時に発生する場合、どのように最適化する必要がありますか?

v-for は v-if よりも先に解析されます. 同時に現れると, 各レンダリングは最初にループを実行してから条件を判断します. いずれにせよ, ループは避けられず, パフォーマンスを浪費します.

このような事態を回避するには、テンプレートを外側のレイヤーにネストし、このレイヤーで v-if 判定を行い、内側で v-for ループを実行します。条件がループ内に表示される場合、表示する必要のない項目は、計算されたプロパティを通じて事前に除外できます。

Vue コンポーネント化の理解

  1. コンポーネントは、独立した再利用可能なコードの組織単位です。コンポーネント システムは、Vue のコア機能の 1 つです。これにより、開発者は、小さくて独立した、再利用可能なコンポーネントを使用して大規模なアプリケーションを構築できます。

  2. コンポーネント開発により、アプリケーション開発の効率、テスト容易性、再利用性などを大幅に改善できます。

  3. コンポーネントの使用法は、ページ コンポーネント、ビジネス コンポーネント、一般コンポーネントに分類されます。

  4. Vue コンポーネントは構成に基づいています. 私たちが通常書くコンポーネントは, コンポーネントではなくコンポーネント構成です. フレームワークは後でそのコンストラクタを生成します. それらは VueComponent に基づいており, Vue を拡張します.

  5. Vue の一般的なコンポーネント化テクノロジには、主にコンポーネントの通信、拡張などに使用される属性 prop、カスタム イベント、スロットなどがあります。

  6. コンポーネントは、凝集度が高く、結合度が低い必要があります。

  7. 一方向データフローの原則に従う

Vue 設計原則の理解

  1. プログレッシブ JavaScript フレームワーク: 他の大規模なフレームワークとは異なり、Vue は下から上にレイヤーごとに適用されるように設計されています。Vue のコア ライブラリは、使いやすいだけでなく、サードパーティのライブラリや既存のプロジェクトと簡単に統合できるビュー レイヤーにのみ焦点を当てています。一方、最新のツールチェーンやさまざまなサポート ライブラリと組み合わせると、Vue は複雑な単一ページ アプリケーションを完全に強化することもできます。

  2. 使いやすさ: Vue は、データ応答性、宣言型テンプレート構文、構成ベースのコンポーネント システムなどのコア機能を提供します。これらにより、js、html、および css を記述できる限り、アプリケーションのコア ビジネスに集中する必要があるだけで済み、vue アプリケーションを簡単に記述できます。

  3. 柔軟性: プログレッシブ フレームワークの最大の利点は柔軟性です. アプリケーションが十分に小さい場合, 関数を完了するために vue のコア機能のみが必要になる場合があります. アプリケーションの規模が拡大し続けるにつれて, ルーティング, 状態を徐々に導入する場合があります.管理、vue-cli そのようなライブラリとツールは、アプリケーションの量であろうと学習の難しさであろうと、徐々に増加する平坦な曲線です。

  4. 効率: 超高速の仮想 DOM と差分アルゴリズムにより、アプリケーションは最高のパフォーマンスを発揮します。vue3 に Proxy を導入してデータの応答性を向上させたり、コンパイラでの静的コンテンツのコンパイルを改善したりすることで、vue はより効率的になります。

Vue のライフサイクルについて話す

Vue インスタンスには完全なライフサイクル、つまり、作成の最初から、データの初期化、テンプレートのコンパイル、Dom のマウント -> レンダリング、更新 -> レンダリング、アンロードなどの一連のプロセスがあります。これをVue のライフサイクル。

  1. beforeCreate(作成前): データ監視および初期化イベントはまだ開始されていません. この時点では、データおよびイベント/ウォッチャーのレスポンシブ トラッキングは設定されていません。アクセスされます。

  2. created(作成後): インスタンスが作成され、インスタンスで構成されたオプション (データ、計算、ウォッチ、メソッドなど) がすべて構成されますが、レンダリングされたノードはこの時点で DOM にマウントされていないため、$ el 属性にアクセスできません。

  3. beforeMount(マウント前): マウントが開始される前に呼び出され、関連するレンダー関数が初めて呼び出されます。インスタンスは次の構成を完了しました: テンプレートをコンパイルし、データ内のデータとテンプレートから html を生成します。この時点では、ページに html はマウントされていません。

  4. mounted(マウント後): el が新しく作成された vm.$el に置き換えられ、インスタンスにマウントされた後に呼び出されます。この例では、次の構成が完了しています。el 属性が指す DOM オブジェクトを、上記のコンパイル済みの html コンテンツに置き換えます。テンプレートの html レンダリングを html ページに完了します。このプロセス中に Ajax 対話が実行されます。

  5. beforeUpdate(更新前): レスポンシブ データが更新されたときに呼び出されます.この時点では、レスポンシブ データは更新されていますが、対応する実際の DOM はレンダリングされていません。

  6. updated(更新後): 仮想 DOM が再レンダリングされ、データの変更によりパッチが適用された後に呼び出されます。この時点で、DOM はレスポンシブ データの変更に従って更新されています。呼び出されると、コンポーネント DOM が更新されているため、DOM に依存する操作を実行できます。ただし、ほとんどの場合、更新の無限ループが発生する可能性があるため、この間に状態を変更することは避ける必要があります。このフックは、サーバー側のレンダリング中には呼び出されません。

  7. beforeDestroy(破棄前): インスタンスが破棄される前に呼び出されます。このステップでは、インスタンスはまだ完全に利用可能であり、これはまだインスタンスを取得できます。

  8. destroyed(破棄後): インスタンスが破棄された後に呼び出されます. 呼び出し後、Vue インスタンスによって示されるすべてのバインドが解除され、すべてのイベント リスナーが削除され、すべてのサブインスタンスが破棄されます。このフックは、サーバー側のレンダリング中には呼び出されません。

さらに、キープアライブには独自のライフサイクルがあり、それぞれアクティブ化および非アクティブ化されます。キープアライブでラップされたコンポーネントは、切り替え時に破棄されませんが、メモリにキャッシュされ、非アクティブ化されたフック関数が実行されます.キャッシュ レンダリングにヒットした後、アクティブ化されたフック関数が実行されます.

Vue 子コンポーネントと親コンポーネントの実行順序

レンダー パスをロードします。

  1. 親コンポーネント beforeCreate

  2. 親コンポーネントが作成されました

  3. 親コンポーネント

  4. 作成前のサブコンポーネント

  5. サブコンポーネントが作成されました

  6. サブコンポーネント beforeMount

  7. サブコンポーネント搭載

  8. マウントされた親コンポーネント

更新プロセス:

  1. 親コンポーネント beforeUpdate

  2. サブコンポーネント beforeUpdate

  3. サブコンポーネントが更新されました

  4. 親コンポーネントが更新されました

破壊プロセス:

  1. 親コンポーネント beforeDestroy

  2. サブコンポーネント beforeDestroy

  3. サブコンポーネントの破壊

  4. 親コンポーネントが破壊されました

作成とマウントの違い

created: テンプレートが html にレンダリングされる前に呼び出されます。つまり、通常、いくつかの属性値が初期化されてから、ビューにレンダリングされます。

マウント: テンプレートが html にレンダリングされた後、通常は初期化ページが完了した後に呼び出され、必要な操作が html の dom ノードで実行されます。

一般に、非同期データを要求するライフサイクル

これらの 3 つのフック関数では、データが作成され、サーバーから返されたデータを割り当てることができるため、これらの 3 つのフック関数を呼び出すことができます。

作成したフック関数で非同期リクエストを呼び出すことをお勧めします、作成されたフック関数で非同期リクエストを呼び出すと、次の利点があるためです。

サーバー データをより速く取得し、ページの読み込み時間を短縮し、ユーザー エクスペリエンスを向上させることができます。

SSR は beforeMount およびマウントされたフック関数をサポートしていません。それらを created に配置すると、一貫性が保たれます。

キープアライブのライフサイクルとは

keep-alive は Vue が提供する組み込みコンポーネントであり、コンポーネントをキャッシュするために使用されます。コンポーネントの切り替え中に状態をメモリに保持して、DOM のレンダリングが繰り返されるのを防ぎます。

コンポーネントのキープアライブがラップされている場合、さらに 2 つのライフサイクル (非アクティブ化とアクティブ化) があります。同時に、コンポーネントが実際に破棄されないため、 beforeDestroy と destroy はトリガーされなくなります。

コンポーネントが置き換えられると、メモリにキャッシュされ、非アクティブ化されたライフ サイクルがトリガーされます。コンポーネントが元に戻されると、キャッシュに移動してコンポーネントが検出され、アクティブ化されたフック関数がトリガーされます。

ルーティングのハッシュ モードと履歴モードの違い

Vue-Router には、ハッシュ モードと履歴モードの 2 つのモードがあります。デフォルトのルーティング モードはハッシュ モードです。

  1. ハッシュモード

はじめに: ハッシュ モードは開発中のデフォルト モードです. URL には # が含まれます (例: http://www.abc.com/#/vue )。ハッシュ値は #/vue です。

機能: ハッシュ値は URL に表示されますが、HTTP 要求には表示されず、バックエンドにはまったく影響しません。したがって、ハッシュ値を変更してもページはリロードされません。このモードのブラウザー サポートは非​​常に優れており、下位バージョンの IE ブラウザーもこのモードをサポートしています。ハッシュ
ルーティングはフロントエンド ルーティングと呼ばれ、SPA (Single Page Application) の標準構成になっています。

原則: ハッシュ モードの主な原則は onhashchange() イベントです。

ここに画像の説明を挿入

onhashchange() イベントを使用する利点は、ページのハッシュ値が変更されたときに、
ウィンドウがイベントの変更を監視し、バックエンドへのリクエストを開始することなく、ルールに従って対応するコードをロードできることです。また、ハッシュ値の変化に対応したURLがブラウザに記録される
ため、ブラウザはページの前後移動を実現できます。バックエンド サーバーへのリクエストはありませんが、ページのハッシュ値は対応する URL に関連付けられています。

  1. 履歴モード

はじめに: 履歴モードの URL には # がなく、従来のルーティング分散モードを使用します。つまり、ユーザーが URL を入力すると、サーバーは要求を受け取り、URL を解析し、対応する論理処理を行います。

機能: 履歴モードを使用する場合、URL はhttp://abc.com/user/idのようになります。ハッシュモードよりも見栄えがします。ただし、履歴モードにはバックグラウンド構成のサポートが必要です。背景が正しく設定されていないと、アクセス時に 404 が返されます。

API: 履歴 API は、履歴状態の切り替えと履歴状態の変更の 2 つの部分に分けることができます。

履歴状態の変更: HTML5 History Interface に新しく追加された pushState() および replaceState() メソッドを含め、これら 2 つのメソッドはブラウザーの履歴スタックに適用され、履歴を変更する機能を提供します。彼らが変更を加えたときに、URL が変更されても、ブラウザはすぐにバックエンドにリクエストを送信しません。ページを更新せずに URL を変更したい場合は、フロント エンドでこれら 2 つの API を使用する必要があります。

スイッチ履歴ステータス: forward()、back()、go() の 3 つのメソッドを含み、ブラウザの forward、backward、および jump 操作に対応します。

履歴モードは醜い # を破棄しますが。ただし、それには独自の欠点もあります。つまり、ページが更新されたときに、対応するルートまたはリソースがない場合、404 が表示されます。

履歴モードに切り替えたい場合は、以下を構成する必要があります (バックエンドも構成する必要があります)。

ここに画像の説明を挿入

  1. 2 つのモードの比較

ハッシュを直接変更する場合と比較して、 history.pushState() の呼び出しには次の利点があります。

pushState() によって設定される新しい URL は、現在の URL と同じソースを持つ任意の URL にすることができますが、ハッシュは # の後の部分のみを変更できるため、現在の URL と同じドキュメントの URL のみを設定できます。

pushState() によって設定された新しい URL は現在の URL とまったく同じである可能性があり、これによりレコードもスタックに追加されますが、ハッシュによって設定された新しい値は、アクションをトリガーしてレコードを追加するために元の値とは異なる必要があります。スタックへ。

pushState() は stateObject パラメーターを介して任意のタイプのデータをレコードに追加できますが、ハッシュは短い文字列しか追加できません。

pushState() は、後で使用するために title 属性を追加で設定できます。

ハッシュ モードでは、ハッシュ記号の前の URL のみがリクエストに含まれます。バックエンドがルートを完全にカバーしていない場合、404 エラーは返されません。適切な URL がない場合、リクエストの URL は同じです。ルート処理を行うと、404 エラーが返されます。

ハッシュモードとヒストリーモードにはそれぞれ一長一短があり、実際の状況に応じて使い分ける必要があります。

Vue-router jump と location.href の違いは何ですか?

location.href= /url を使用してジャンプします。シンプルで便利ですが、ページを更新します。history.pushState( /url ) を使用し、ページを更新せず、静的ジャンプします。

ルーターを導入し、router.push(/url) でジャンプし、diff アルゴリズムを使用し、オンデマンド ロードを実現し、dom の消費を減らします。実際、vue-router は特に履歴モードで history.pushState() を使用するため、ルーターを使用してジャンプする場合と history.pushState() を使用する場合に違いはありません。

Vuexの原理

Vuex は、Vue.js アプリケーション専用に開発された状態管理パターンです。すべての Vuex アプリケーションの中心はストアです。「ストア」は基本的に、アプリケーションの状態の大部分を保持するコンテナです。

Vuex のステート ストアはリアクティブです。Vue コンポーネントがストアから状態を読み取るときに、ストアの状態が変化すると、それに応じて対応するコンポーネントが効率的に更新されます。

ストアの状態を変更する唯一の方法は、ミューテーションを明示的にコミットすることです。これにより、すべての状態変化を簡単に追跡できます。
ここに画像の説明を挿入

Vuex は、開発中の API 呼び出しを含む、Vue コンポーネントの完全なエコシステムを構築しました。

  1. コア プロセスの主な機能:

Vue コンポーネントは vue コンポーネントであり、コンポーネントはいくつかのイベントまたはアクション (図のアクション) をトリガー (ディスパッチ) します。

コンポーネントで送信されるアクションは、データを取得または変更する必要がありますが、vuex では、データは一元管理され、データを直接変更することはできないため、アクションはミューテーションに送信 (コミット) されます。

その後、ミューテーションは (Mutate) State のデータを変更します。

State のデータが変更されると、Vue コンポーネントに再レンダリング (Rendered) され、コンポーネントは更新されたデータを表示してプロセスを完了します。

  1. コア プロセスの各モジュールの主な機能:

Vue コンポーネント: Vue コンポーネント。HTML ページでは、ユーザー操作などのインタラクティブなアクションを受け取り、dispatch メソッドを実行して、対応するアクションをトリガーして応答します。

ディスパッチ: アクションを実行できる唯一のメソッドである操作動作トリガー メソッド。

actions: アクション処理モジュール。Vue コンポーネントが受け取るすべての対話を処理する責任があります。同期/非同期操作を含み、同じ名前の複数のメソッドをサポートし、登録順にトリガーします。バックグラウンド API に要求された操作は、他のアクションのトリガーやミューテーションの送信など、このモジュールで実行されます。このモジュールは、Promise のカプセル化を提供して、アクションのチェーン トリガーをサポートします。

commit: 状態変更コミット操作メソッド。ミューテーションを送信することが、ミューテーションを実行する唯一の方法です。

突然変異: 状態変更操作方法。これは、Vuex が状態を変更する唯一の推奨される方法です。他の変更方法では、strict モードでエラーが報告されます。このメソッドは同期操作のみを実行でき、メソッド名はグローバルに一意である必要があります。操作中、状態監視などのためにいくつかのフックが公開されます。

state: ページ状態管理コンテナ オブジェクト。データ オブジェクトの散在するデータを Vuecomponents に一元的に保存します。これは、統一された状態管理のためにグローバルに一意です。ページ表示に必要なデータはこのオブジェクトから読み取られ、Vue のきめ細かなデータ応答メカニズムを使用して効率的な状態更新が実行されます。

[外部リンクの画像の転送に失敗しました。ソース サイトにリーチング防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-EgYN12F4-1682748429789)(media/image8.png)]getters: 状態オブジェクトの読み取り方法. The module is not listed below in the figure, and should be included in render. Vue コンポーネントは、このメソッドを通じてグローバル状態オブジェクトを読み取ります。

要約:

Vuex は一方向のデータ フローを実装します. データをグローバルに保存する状態があります. コンポーネントが状態のデータを変更したい場合, ミューテーションを通じて変更情報を送信する必要があります. ミューテーションは外部プラグインのサブスクライバー モードも提供します
.状態データの更新を取得するために呼び出します。また、すべての非同期操作 (一般に更新データを非同期に取得するためのバックエンド インターフェイスと呼ばれます) またはバッチ同期操作で Action を使用する必要があるが、Action が State を直接変更できないか、Mutation を介して State データを変更する必要がある場合。最後に、State の変更に応じて、ビューにレンダリングされます。

Vuex と localStorage の違い

  1. 最も重要な違い
  • vuex はメモリに保存されます

  • localstorage はファイルとしてローカルに保存され、文字列型のデータのみを保存できます。保存されたオブジェクトを処理するには、JSON の stringify メソッドと parse メソッドが必要です。メモリの読み取りは、ハードディスクの読み取りよりも高速です

  1. 適用シナリオ
  • Vuex は、Vue.js アプリケーション専用に開発された状態管理パターンです。集中ストレージを使用してアプリケーションのすべてのコンポーネントの状態を管理し、対応するルールを使用して、状態が予測可能な方法で変化するようにします。Vuex は、コンポーネント間で値を渡すために使用されます。

  • localstorage は、ブラウザにデータを保存する方法であるローカル ストレージであり、通常、ページ間でデータを転送するときに使用されます。

Vuex はデータの応答性を実現できますが、localstorage は実現できません

  1. 永続

vuex によって保存された値は、ページが更新されると失われますが、localstorage は失われません。

注: 変化しないデータには vuex の代わりに Localstorage を使用できますが、2 つのコンポーネントがデータ ソース (オブジェクトまたは配列) を共有している場合、コンポーネントの 1 つがデータ ソースを変更し、もう 1 つのコンポーネントがその変更に応答する場合、localstorage は使用できません。それ、理由は違い1です。

Redux と Vuex の違いと共通の考え方

  1. Redux と Vuex の違い

Vuex は Redux の Action および Reducer 関数を改善し、Reducer をミューテーション変更関数に置き換えます。スイッチなしで、対応するミューテーション関数の状態値を変更するだけです。

Vuex Vue の自動再レンダリング機能により、新しい State が生成される限り、再レンダリング機能にサブスクライブする必要はありません。

Vuex データ フローのシーケンスは次のとおりです。ビューは store.commit を呼び出して、対応する要求をストア内の対応するミューテーション関数に送信します -> 変更を保存します (vue はデータの変更を検出し、自動的にレンダリングします)。

vuex はディスパッチを弱め、コミットによってストアの状態を変更する、アクションの概念をキャンセルし、指定された変更に対して特定のアクション フォームを渡す必要がない、レデューサーを弱め、コミット パラメータに基づいてデータを直接変更する、というのが一般的な理解です。フレームワークはより単純です。

  1. 共通の考え
    単一ソースのデータ
    変更は予測可能

本質的には、redux と vuex の両方が、ビューからデータを抽出するソリューションである mvvm のアイデアに役立ちます。

形式に関しては、vuex は redux から借用し、ストアをモード管理用のグローバル データ センターとして使用します。

Vuex または Redux を使用する理由

パラメーターを渡す方法は、多層のネストされたコンポーネントでは非常に面倒であり、兄弟コンポーネント間の状態転送については何もできないためです。多くの場合、親子コンポーネントを使用してイベントを直接参照または渡し、状態の複数のコピーを変更および同期します。上記のパターンは非常に脆く、多くの場合、保守不能なコードになります。

そのため、コンポーネントの共有状態を抽出し、グローバルシングルトンモードで管理する必要があります。このモードでは、コンポーネント ツリーは巨大な「ビュー」を形成し、ツリー内のどこにあるかに関係なく、どのコンポーネントでも状態を取得したり、動作をトリガーしたりできます。

さらに、状態管理のさまざまな概念を定義して分離し、特定のルールを適用することで、コードはより構造化され、保守しやすくなります。

Vuex にはどのようなプロパティがありますか?

State、Getter、Mutation、Action、Module の 5 つのタイプがあります。

状態 => 基本データ (データ ソースの保存場所)

getters => ベースデータから派生したデータ

ミューテーション => 変更されたデータを送信するメソッド、同期

actions => は、ミューテーションをラップして非同期にするデコレータのようなものです。

モジュール => モジュラー Vuex

Vuex とプレーンなグローバル オブジェクトの違いは何ですか?

Vuex のステート ストアはリアクティブです。Vue コンポーネントがストアから状態を読み取るときに、ストアの状態が変化すると、それに応じて対応するコンポーネントが効率的に更新されます。

ストアの状態を直接変更することはできません。ストアの状態を変更する唯一の方法は、ミューテーションを明示的にコミットすることです。これにより、すべての状態変化を簡単に追跡できるようになり、ツールがアプリケーションをよりよく理解できるようになります。

Vuex のミューテーションで非同期操作を実行できないのはなぜですか?

Vuex ですべての状態を更新する唯一の方法はミューテーションです.非同期操作は、アクションを介してミューテーションを送信することによって実装されます.これにより、各状態の変更を簡単に追跡し、アプリケーションをよりよく理解するのに役立ついくつかのツールを実装できます.

各ミューテーションが実行されると、新しい状態変化に対応するため、devtools はスナップショットを作成して保存し、タイムトラベルを実現できます。

ミューテーションが非同期操作をサポートしている場合、状態がいつ更新されるかを知る方法がなく、状態をうまく追跡することができないため、デバッグが困難になります。

Vue3.0 の新機能

  1. 監視メカニズムの変更

3.0 では、プロキシProxyベースの、リアクティブ トレースの完全な言語カバレッジが提供されます。

Vue 2 でのObject.defineProperty ベース:

  1. オブジェクトではなく、属性のみを監視できます

属性の追加と削除を検出します。

配列のインデックスと長さの変化を検出します。

Map、Set、WeakMap、および WeakSet をサポートします。

  1. テンプレート
    スコープ スロット。2.x メカニズムによりスコープ スロットが変更され、親コンポーネントが再レンダリングされますが、3.0 ではスコープ スロットが子コンポーネントの再レンダリングにのみ影響する関数に変更され、レンダリング パフォーマンスが向上します。 .
    同時に、render 関数の側面についても、vue3.0 は一連の変更を行い、API を直接使用して vdom を生成する習慣を容易にします。

  2. オブジェクトベースのコンポーネント宣言

vue2.x のコンポーネントは一連のオプションを宣言で渡します.TypeScript との組み合わせはいくつかのデコレータを介して行う必要があります.機能を実現することはできますが、面倒です.

3.0 コンポーネントの宣言方法を変更し、TypeScriptと組み合わせやすいクラススタイルに変更

  1. その他の変更

カスタム レンダラーをサポートして、フォーク ソース コードを直接変更する代わりに、カスタム レンダラーによって weex を拡張できるようにします。

Fragment (複数のルート ノード) および Portal (DOM の他の部分でコンポーネント コンテンツをレンダリングする) コンポーネントをサポートし、いくつかの特別なシナリオを処理します。

ツリー シェーキングの最適化に基づいて、より多くの組み込み関数を提供します。

defineProperty とプロキシの違い

インスタンスが初期化されると、Vue はデータ内のすべてのプロパティをトラバースし、Object.defineProperty を使用してこれらすべてのプロパティをゲッター/セッターに変換します。このようにして、追跡データが変更されると、setter が自動的に呼び出されます。

Object.defineProperty は ES5 ではシムできない機能です。そのため、Vue は IE8 およびそれ以前のバージョンのブラウザーをサポートしていません。

しかし、そうすると次のような問題があります。

  1. Vue は、オブジェクトのプロパティがいつ追加または削除されたかを検出しません。追加または削除されたオブジェクトは応答処理用に初期化されていないため、$set を介して Object.defineProperty() を呼び出すことによってのみ処理できます。

  2. 添字と配列の長さの変更は監視できません。

Vue3 は Proxy を使用してデータの変更を監視します。Proxy は ES6 で提供される関数です. その役割は: 基本操作 (属性検索、代入、列挙、関数呼び出しなど) のカスタム動作を定義することです。Object.defineProperty() と比較すると、次の特徴があります。

  1. プロキシは、オブジェクト プロパティではなくオブジェクト全体を直接プロキシするため、プロキシの 1 つのレイヤーのみを使用して、プロパティの追加と削除を含む、同じレベル構造の下にあるすべてのプロパティの変更を監視できます。

  2. プロキシは、アレイの変更を監視できます。

なぜ Vue3.0 はプロキシを使用するのですか?

Vue2 では、0bject.defineProperty は元のデータを変更し、Proxy はオブジェクトの仮想表現を作成し、set、get、deleteProperty などのプロセッサを提供し、元のオブジェクトのプロパティにアクセスまたは変更するときにインターセプトできます。次の機能:

反応性をトリガーするために Vue.$set または Vue.$delete を使用する必要はありません。

Vue2 の無効なエッジ ケースを排除する、配列変更検出の全範囲。

Map、Set、WeakMap、WeakSet をサポートします。

Proxy によって実装されるレスポンシブの原則は Vue2 のものと同じであり、実装方法も似ています。

  • get は依存関係を収集します

  • トリガーの依存関係の設定、削除など

  • コレクション型の場合、コレクション オブジェクトのメソッドをパッケージ化するレイヤーです。元のメソッドが実行された後、依存関係に関連するコレクションまたはトリガー ロジックが実行されます。

仮想 DOM の解析プロセス

首先对将要插入到文档中的 DOM 树结构进行分析,使用 js 对象将其表示出来,比如一个元素对象,包含 TagName、props 和 Children这些属性。然后将这个 js 对象树给保存下来,最后再将 DOM 片段插入到文档中。

当页面的状态发生改变,需要对页面的 DOM 的结构进行调整的时候,首先根据变更的状态,重新构建起一棵对象树,然后将这棵新的对象树和旧的对象树进行比较,记录下两棵树的的差异。

最后将记录的有差异的地方应用到真正的 DOM 树中去,这样视图就更新了。

差分アルゴリズムの原理

古い仮想 DOM と新しい仮想 DOM を比較すると、次のようになります。

まず、ノード自体を比較して同じノードかどうかを判断し、そうでない場合はノードを削除し、ノードを再作成して置き換えます

同じノードの場合は、patchVnode を実行して、ノードの子ノードの処理方法を決定します. まず、一方に子ノードがあり、もう一方に子ノードがない状況を判断します (新しい子に子ノードがない場合は、削除します)。すべての子ノード
がある場合は、updateChildren を実行して、
これらの古いノードと新しいノードの子ノードを操作する方法を決定します (diff コア)。

マッチング時、同じ子ノードを見つけ、再帰的に子ノードを比較する

diff では、同じ層の子ノードのみが比較され、レベル間のノード比較は破棄されるため、時間の複雑さが O(n3) から O(n) に削減されます。新しい子は複数の子ノードです 同じレベルの比較には、コア Diff アルゴリズムを使用するだけで済みます。

Vue でのキーの役割

vue でのキー値の役割は、次の 2 つのケースで考えることができます。

最初のケースは、v-if でキーを使用する場合です。Vue は要素を可能な限り効率的にレンダリングするため、既存の要素を最初からレンダリングするのではなく、再利用するのが一般的です。したがって、v-if を使用して要素の切り替えを実装する場合、切り替えの前後に同じ型の要素がある場合、この要素が再利用されます。同じ入力要素の場合、切り替え前後でユーザーの入力がクリアされず、要件を満たしていません。したがって、要素はキーを使用して一意に識別できますが、この場合、キーを使用する要素は再利用されません。このとき、キーの機能は独立した要素を識別することです。

2 番目のケースは、v-for でキーを使用する場合です。v-for を使用してレンダリングされた要素のリストを更新する場合、デフォルトで「インプレース再利用」戦略が使用されます。データ項目の順序が変更された場合、Vue はデータ項目の順序に合わせて DOM 要素を移動せず、ここで各要素を再利用するだけです。したがって、各リスト項目にキー値を提供することにより、Vue は要素の ID を追跡して、効率的な再利用を実現できます。このとき、キーの機能は、仮想 DOM を効率的に更新およびレンダリングすることです。

キーは Vue の vnode の一意のマークです。このキーを使用すると、差分操作がより正確かつ高速になります。

更准确: key によるインプレース多重化ではないため、sameNode 関数 a.key=== b.key 比較でインプレース多重化を回避できます。したがって、より正確になります。

更快速: キーの一意性を使用してマップ オブジェクトを生成し、対応するノードを取得します。これは、トラバーサル メソッドよりも高速です。

次号でReact部分を更新

おすすめ

転載: blog.csdn.net/qq_37215621/article/details/130440341