この記事では、Vue 3.0 レスポンシブの使い方を説明します。

この記事では、Vue 3.0 レスポンシブの使い方を説明します。

Vue 2.0 Ojbect.definePropertyを使用してオブジェクトの既存のプロパティ値の読み取りと変更をハイジャックすることがわかっていますが、このAPIオブジェクトのプロパティの追加と削除を監視できません。また、オブジェクトの内部プロパティを深くハイジャックするには、初期化中に内部プロパティに対してOjbect.defineProperty再帰的に呼び出す必要があり、パフォーマンスの消費を引き起こします。これらの問題を解決するために、 Vue 3.0ではProxyを使用してレスポンシブ ロジックを書き直し、関連するパフォーマンスを最適化しました。

ユースケース

Vue 3.0でレスポンシブ API を書く方法の例を見てみましょう。

場合

changePerson 、レスポンシブ データpersonの値を変更できます。 person値の変更により、コンポーネントの再レンダリングがトリガーされ、 DOMが更新されます。

ここで、 Vue 3.0の使用において、開発者はreactive関数を使用してどのデータがレスポンシブ データであるかを判断し、不要なレスポンシブ パフォーマンスの消費を回避していることがわかります。たとえば、この場合、 nowIndexレスポンシブ データにする必要はありません。 (もちろん、 Vue 2.0 data関数の外で非レスポンシブなデータを定義することもできます)

次に、 reactive関数の実装原理を見てみましょう。

リアクティブAPI関連プロセス

反応的な

反応的な

コードの説明:

  • 1. ターゲットオブジェクトが読み取り専用targetの場合、読み取り専用オブジェクトは応答オブジェクトとして設定できないため、ターゲットオブジェクトを直接返します。
  • 2. createReactiveObject関数を呼び出してプロセスを続行します。

createReactiveObjectはレスポンシブオブジェクトを作成します

アクティブオブジェクトを作成する

コードの説明:

  • 1. 対象オブジェクトがデータまたはオブジェクトでない場合は、オブジェクトが直接返され、開発環境でエラー警告プロンプトが表示されます。
  • 2. targetがすでにProxyオブジェクトである場合、 target, (target['__v_raw']は非常に巧妙に設計されています。 targetProxyオブジェクトである場合、 target['__v_raw']getメソッドをトリガーし、キャッシュ オブジェクトreactiveMap検索して、 targetオブジェクトのProxyオブジェクトがtarget自体と等しいかどうかを確認します)。ここで例外が処理されます。レスポンシブ オブジェクトでreadonly関数が実行された場合は、続行する必要があります。
  • 3. reactiveMap内に対応するProxyオブジェクトがあるかどうかを確認し、対応するProxyオブジェクトを直接返します。
  • 4. 特定のデータのみがレスポンシブになるようにし、そうでない場合はtargetを返すだけにします。レスポンシブホワイトリストは次のようになります。

1. targetmarkRawメソッドによってマークされていないか、 targetオブジェクトに__v_skip属性値がないか、 __v_skip属性の値がfalseです。

2. target拡張不可能なオブジェクトであってはなりません。つまり、 target preventExtensionssealおよびfreezeメソッドを使用して実行されていません。

3. targetObjectまたはArrayです。

4. targetMapSetWeakMapWeakSetです。

  • 5. Proxy機能を使用してtargetオブジェクトをハイジャックすると、返される結果は応答オブジェクトになります。ここでの処理関数は、 targetオブジェクトによって異なります (両方の関数がパラメーターとして渡されます)。

1. ObjectまたはArrayの処理関数はcollectionHandlersです。

2. MapSetWeakMapWeakSetの処理関数はbaseHandlersです。

  • 6. レスポンシブ オブジェクトをキャッシュのreactiveMapに保存します。 keytargetvalueproxyです。

mutableHandlers 処理関数

可変ハンドラ

オブジェクトのプロパティにアクセスするとget関数がトリガーされ、オブジェクトのプロパティを設定するとset関数がトリガーされ、オブジェクトのプロパティを削除するとdeleteProperty関数がトリガーされ、 in has関数がトリガーされ、 getOwnPropertyNamesによってownKeys関数がトリガーされることがわかっています。次に、これらの関数のコード ロジックを見てみましょう。

関数を取得する

パラメータが渡されないため、デフォルトではisReadonlyshallow両方とも false になります。

得る

コードロジック:

  • 1. __v_isReactive属性が取得され、true が返された場合、ターゲットがすでにレスポンシブなオブジェクトであることを意味します。
  • 2. __v_isReadonly属性を取得し、false を返します。(readonly は別のレスポンシブ API ですが、ここでは説明しません)
  • 3. __v_raw属性を取得し、ターゲット自体を返します。この属性は、ターゲットがすでにレスポンシブなオブジェクトであるかどうかを判断するために使用されます。
  • 4. ターゲットが配列であり、includes、indexOf、lastIndexOfなどの属性にヒットした場合、配列のこれらの関数メソッドが実行され、配列の各要素に対してコレクション依存関係トラック( arrTrackOpTypes.GETi + '')が実行され、Reflectを通じて配列関数の値が取得されます。
  • 5.評価を反映する。
  • 6. それが特別な属性値であるかどうかを判断します: symbol__proto____v_isRef__isVu e。以前に取得した res に直接返される場合、後続の処理は実行されません。
  • 7.コレクションの依存関係を実行します。
  • 8. ref の場合、target が配列でないか、key が整数でない場合は、データの展開が実行されます。これには別のレスポンシブ API ref が関係しますが、ここでは説明しません。
  • 9. res がオブジェクトの場合、 reactive を再帰的に実行して、 res をレスポンシブ オブジェクトに変換します。ここで、ちょっとした最適化のヒントを紹介します。プロパティ値はアクセスされた後にのみハイジャックされるため、初期化中に完全にハイジャックされることによるパフォーマンスの消費を回避できます。

get関数を呼び出すタイミング

この質問に答える前に、セットアップに関する前回の記事「 Vue3.0 セットアップ機能の謎を解明」に戻る必要があります。

  • setup() 関数はsetupStatefulComponent関数内で実行され、実行結果が得られます。

セットアップステートフルコンポーネント

  • handleSetupResultのロジックは、間隔setupResultinstance.setupStateに割り当てることです。

ハンドルセットアップ結果

  • このinstance.setupStateinstance.ctxによってプロキシされるため、 instance.ctxにアクセスして変更すると、 instance.setupStateに直接アクセスして変更できます。

ctx

  • サブツリーVNodeレンダリングするには、 render関数を呼び出す必要があると前に説明しました。テンプレート コンパイルを使用して、例のrender関数がどのようになっているかを確認してみましょう。

与える

  • 非常に明確です。テンプレートをレンダリングするときに、 person属性オブジェクトはctxから取得されますが、これは実際にはsetupStateperson属性オブジェクトです。 setupStateperson属性オブジェクトのnameageaddressが取得されると、対応する値を取得するためにget関数が呼び出されます。

概要: コンポーネント インスタンス オブジェクトがレンダリング関数を実行してサブツリー VNode を生成すると、レスポンシブ オブジェクトの get 関数が呼び出されます。

トラックは依存関係を収集します

上記のget関数のコード説明でコレクション依存性について2 回言及しましたが、コレクション依存性とは何でしょうか?
応答性を実現するために、データが変更されたときに特定の関数を実行するなど、一部の機能が自動的に実装されます。副作用レンダリング関数はコンポーネントの再レンダリングをトリガーして DOM を更新できるため、ここで収集される依存関係は、データが変更されたときに実行する必要がある副作用レンダリング関数です。

つまり、 get関数が実行されると、対応するコンポーネントの副作用レンダリング関数が収集されます。

追跡

トラクト効果

最終結果を説明するために、次の例を挙げます。

結果

関数の設定

セット

コードロジック:

  • 1. 値が変更されていない場合は直接戻ります。
  • 2. Reflectを通じて新しい値を設定します。
  • 3. プロトタイプ チェーン上のプロパティではなく、新しいプロパティの場合はadd type triggerを実行し、変更されたプロパティの場合はset type triggerを実行します。 (Reflect.set がプロトタイプ チェーン上のプロパティである場合、セッターが再度呼び出されるため、トリガーを 2 回実行する必要はありません)。

トリガー分布の依存関係

トリガー

triggerコードのロジックは非常に明確です。get 関数によって収集された依存関係の targetMap から対応する関数を見つけ、これらの副作用レンダリング関数を実行して DOM を更新します。

取得と副作用レンダリング関数の関連付け

戻って別の質問に答えましょう。get 関数から収集された副作用レンダリング関数はどのように決定されるのでしょうか。つまり、person.name にアクセスするときに関連付ける副作用レンダリング関数をどのように決定するのでしょうか。

ロジックを段階的に整理してみましょう。

  • mountComponentをマウントする最後のステップは、副作用のあるレンダリング関数を実行することです。

マウントコンポーネント

  • setupRenderEffect 、最初にcomponentUpdateFnコンポーネント レンダリング関数を定義し、次にこのomponentUpdateFnReactiveEffectにカプセル化し、 ReactiveEffectオブジェクトのrunメソッドをコンポーネント オブジェクトのupdateプロパティに割り当て、次にupdateメソッドを実行します。このメソッドは、実際にはReactiveEffectオブジェクトのrunメソッドを実行します。

セットアップレンダリングエフェクト

  • ReactiveEffectの run メソッドは渡された関数を保持し、現在のシーンはcomponentUpdateFnコンポーネント レンダリング関数であり、2 つのグローバル変数effectStackactiveEffect使用します。
  • run メソッドを実行すると、まずcomponentUpdateFnactiveEffectに割り当てられ、 effectStackスタックにプッシュされ、次にcomponentUpdateFnメソッドが実行されます。実行が完了すると、 componentUpdateFnがスタックからポップされ、 activeEffectがスタックの先頭に新しい関数として割り当てられます。

リアクティブエフェクト

  • componentUpdateFnが実行されると、 renderComponentRootが呼び出され、基本的にコンポーネント インスタンス オブジェクトの render メソッドが実行されます。

コンポーネント更新関数

  • ここまででこの記事の内容です。renderメソッドで対応するデータにアクセスすると、get関数が呼び出されます。getで収集されるデータは

トラクト効果

ここでのスタック構造は、主にネストされた効果の問題を解決するために設計されています。

副作用レンダリング関数の実行フィルタリング

よく考えてみると疑問が湧いてくるのではないでしょうか?名前、年齢、住所はすべて変更されており、すべて同じレンダリング関数に関連付けられています。理論上、これら 3 つの値を同時に変更すると、3 つのコンポーネントの再レンダリングがトリガーされますが、これは明らかに不合理です。では、Vue はどのようにして実行を 1 回だけ制御するのでしょうか?

  • ReactiveEffect componentUpdateFnレンダリング関数をカプセル化するところに戻る必要があります。2 番目のパラメータ、 schedulerを見てみましょう。

リアクティブエフェクト

  • 依存関係をディスパッチするときに、 schedulerがある場合は、 schedulerが実行されます。

ここに画像の説明を挿入

  • queueJobの実行ロジックは、タスクがキュー内にある場合はそれをフィルタリングして実行しないことです。

キュージョブ

結論

この記事では、Vue3.0のレスポンシブ原則について詳しく紹介します。Proxyを使用してオブジェクトをハイジャックすると、オブジェクトにアクセスするときにgetメソッドがトリガーされ、このときに依存関係が収集されます。オブジェクトデータが変更されると、setメソッドがトリガーされ、依存関係がディスパッチされます。つまり、コンポーネントの副作用レンダリング関数が呼び出されます(これに限定されません)。これにより、コンポーネントが再レンダリングされ、DOMが更新されます。

これで、vue3.0 の応答性に関するこの記事は終了です。vue3.0 の応答性に関するより関連性の高いコンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • 夕食後にVue3.0のレスポンシブデータについてお話しましょう
  • Vue3.0 レスポンシブ システムのソース コードの行ごとの分析
  • Vue3.0データ応答原則の詳細な説明
  • Vue3.0 でレスポンシブデータを実装する方法をご存知ですか?
  • Vue3.0 レスポンシブ機能の原理の詳細

<<:  MySQLビューの原理と使用法の詳細な説明

>>:  MySQL インデックスの原理と使用例の分析

推薦する

Vue3における非親子コンポーネント通信の詳細な説明

目次最初の方法アプリ.vueホーム.vueホームコンテンツ.vueデータの応答性レスポンシブプロパテ...

CSSでemを開く正しい方法の詳細な説明

「通常 1em=16px」と言うのはなぜですか?ユーザーのブラウザによってレンダリングされるデフォル...

一般的なブラウザのユーザーエージェントの概要

1. 基礎知識: HTTP ヘッダー ユーザーエージェントユーザー エージェントは、ユーザー エージ...

Linux で MySQL スケジュール タスク バックアップ データを実装する方法

序文バックアップは災害復旧の基礎であり、システム操作エラーやシステム障害によるデータ損失を防ぐために...

MySQL マルチマスターと 1 スレーブのデータバックアップ方法のチュートリアル

概要いずれかのデータベースに対する操作は他のデータベースに自動的に適用され、2 つのデータベースのデ...

MySQLからOracleへのリアルタイム同期ソリューションの詳細な説明

1 要件の概要MySQL5.6本番データベースの複数のテーブルのデータは、Oracle11gデータウ...

Nginx の add_header ディレクティブに注意する必要があるのはなぜですか?

序文ご存知のとおり、nginx 構成ファイルは add_header ディレクティブを使用して応答ヘ...

表の境界線の CSS 構文

<br />表の境界線の CSS 構文具体的な内容には、上境界線の幅、右境界線の幅、下境...

JavaScript でイベントのバブリングを防ぐ方法

注意すべき点は、イベントバブリング自体の特性上、メリットだけでなくデメリットも生じるということです。...

MySQL インデックスの設計と最適化の方法

目次インデックスとは何ですか?左端のプレフィックス一致の原則key_lenの計算方法インデックスの最...

HTML の doctype とエンコーディングに関する簡単な説明

文書タイプDoctype は、指示を解析するためにどのバージョンの HTML を使用するかをブラウザ...

webpackでHMRを手動で実装するいくつかの方法

目次1. はじめに2. GitHub 3. 基本構成プロジェクトディレクトリパッケージ.json c...

Element UI で自動サイズ調整テキストエリアの高さを設定する方法

Element UIのtextarea input自動サイズに設定すると、テキストボックスのデフォル...

Vueは、センシティブな単語フィルタリングコンポーネントを検出するためのさまざまなアイデアを実装しています。

目次前面に書かれた要件分析 v1アイデア1: インターセプションメソッドを使用して入力ボックスの入力...

MySQLデータベースにパスワードを入力した後にフラッシュバックする問題の解決策

パスワード入力後にMySQLデータベースがクラッシュする問題と解決策1 ケースの説明最近、基本的な機...