この記事では、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 インデックスの原理と使用例の分析

推薦する

メッセージボードにメッセージを追加および削除するための JavaScript

この記事では、JavaScript メッセージ ボードでメッセージを追加および削除する小さな例を詳細...

Windows 10 での MySQL 5.7.21 winx64 のインストールと設定方法のグラフィック チュートリアル

mysql 5.7.21 winx64 のインストールと設定方法: MySQLのコミュニティバージョ...

便利で使いやすいウェブアプリケーションを設計するための 10 のヒント

より使いやすい Web アプリケーションを設計するための 10 のヒントをご紹介します。ヒント1: ...

タブ切り替えを実装するための HTML サンプル コード

タブ切り替えもプロジェクトではよく使われる技術です。一般的にタブ切り替えはjsやjqを使って実装され...

VueのSSRサーバーサイドレンダリング例の詳細な説明

サーバーサイドレンダリング (SSR) を使用する理由検索エンジンのクローラーが完全にレンダリングさ...

HTML のタイトル、段落、改行、水平線、特殊文字についての簡単な説明

タイトルXML/HTML コードコンテンツをクリップボードにコピー< h1 >第 1 レ...

Vueカスタムカプセル化ボタンコンポーネント

Vueボタンコンポーネントのカスタムカプセル化コードは参考用です。具体的な内容は次のとおりです。ボタ...

MySQLデータ移行の概要

目次序文: 1. データ移行について2. 移行計画と留意点要約:序文:日常業務では、テーブル、データ...

MySQL のデータ統計に関するヒント

よく使用されるデータベースである MySQL では、多くの操作が必要です。デジタル操作には非常に便利...

html オプション 無効 選択 選択 無効 オプションの例

コードをコピーコードは次のとおりです。 <選択> <オプション値="&q...

MySQL 8.0.23 メジャーアップデート (新機能)

著者: Guan Changlong は、Aikesheng の配送サービス部門の DBA です。主...

JavaScript strictモードの概要 strictを使用する

目次1. 概要1.1 厳密モードとは何ですか? 1.2 厳密モードの目的2. 厳密モードを有効にする...

nginxコンテナ設定ファイルの独立した実装

コンテナを作成する [root@server1 ~]# docker run -it --name ...

JavaScript タイマー原理の詳細な説明

目次1. setTimeout() タイマー2. setTimeout() タイマーを停止する3. ...

JavaScript の 3 つの BOM オブジェクト

目次1. 場所オブジェクト1. URL 2. 場所オブジェクトのプロパティ3. ロケーションオブジェ...