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

推薦する

Tomcat Nativeを使用してTomcat IO効率を向上させる方法の詳細な説明

目次導入Tomcatへの接続方法APR と Tomcat ネイティブtomcat で APR を使用...

Faint: 「Web2.0 を使用して標準に準拠したページを作成する」

今日、ある人がウェブサイト開発プロジェクトについて話をしてくれました。具体的な要件について話すと、「...

2つのシンプルなメニューナビゲーションバーの例

メニューバーの例 1: コードをコピーコードは次のとおりです。 <!DOCTYPE html ...

HTML+CSS+JSはナビゲーションバーのスクロールグラデーション効果を実現します

目次まず効果を見てみましょう:成し遂げる:要約:まず効果を見てみましょう: 成し遂げる: 1. ナビ...

Reactの基本のまとめ

目次序文始めるReactライフサイクルリアクトファイバーリアクトセットステートReactイベントメカ...

Dockerイメージ構築原理の分析(Dockerをインストールしなくてもイメージを構築できる)

イメージの構築は、DevOps プロセスにおいて非常に重要なプロセスです。一般的に、イメージの構築と...

タイムスタンプの差を計算するSQLメソッド

タイムスタンプの差を計算するSQLメソッド概要場合によっては、特定のレコードを時間で検索する必要があ...

nginxとlvsのメリットとデメリット、そして適切な使用環境

まず最初に、ロード バランシングとは何かについて説明します。ロード バランシングとは、リクエストの内...

入力スクリプトなしでタイプ拡張を使用する方法

序文JS の型付けが弱く、記述基準が緩く、開発ツールのサポートが弱いため、前任者のコードをメンテナン...

カルーセル効果を作成するためのjs

カルーセルはフロントエンド開発において比較的重要なポイントだと思います。ネイティブjsの知識ポイント...

Vue プロジェクトがページング効果を実現

ページング効果は、参考までにvueプロジェクトに実装されています。具体的な内容は次のとおりです。 1...

Vue のドロップダウン ボックスのセカンダリ リンク効果を実装するためのサンプル コード

1. 成果を達成する 2. バックエンドから返されるデータ形式 「リスト」: [ { "i...

Dockerイメージの階層化の原理の詳細な説明

ベースイメージベースイメージには 2 つの意味があります。他のイメージに依存せず、ゼロから構築します...

jsは赤い封筒の順序と量を指定するアルゴリズムを実装します

この記事では、指定された赤い封筒の順序と金額を実装するためのjsの具体的なコードを共有します。具体的...

Vue + Axios リクエストインターフェース方式とパラメータ渡し方式の詳しい説明

目次1. リクエストを取得する: 2. 投稿リクエスト: 3. 拡張と補足Vue スキャフォールディ...