目次- ユースケース
- リアクティブAPI関連プロセス
- 反応的な
- createReactiveObjectはレスポンシブオブジェクトを作成します
- mutableHandlers 処理関数
- 関数を取得する
- get関数を呼び出すタイミング
- トラックは依存関係を収集します
- 関数の設定
- トリガー配布の依存関係
- 取得と副作用レンダリング関数の関連付け
- 副作用レンダリング関数の実行フィルタリング
- 結論
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'] は非常に巧妙に設計されています。 target がProxy オブジェクトである場合、 target['__v_raw'] はget メソッドをトリガーし、キャッシュ オブジェクトreactiveMap 検索して、 target オブジェクトのProxy オブジェクトがtarget 自体と等しいかどうかを確認します)。ここで例外が処理されます。レスポンシブ オブジェクトでreadonly 関数が実行された場合は、続行する必要があります。 - 3.
reactiveMap 内に対応するProxy オブジェクトがあるかどうかを確認し、対応するProxy オブジェクトを直接返します。 - 4. 特定のデータのみがレスポンシブになるようにし、そうでない場合は
target を返すだけにします。レスポンシブホワイトリストは次のようになります。
1. target がmarkRaw メソッドによってマークされていないか、 target オブジェクトに__v_skip 属性値がないか、 __v_skip 属性の値がfalse です。 2. target 拡張不可能なオブジェクトであってはなりません。つまり、 target preventExtensions 、 seal およびfreeze メソッドを使用して実行されていません。 3. target はObject またはArray です。 4. target はMap 、 Set 、 WeakMap 、 WeakSet です。 - 5.
Proxy 機能を使用してtarget オブジェクトをハイジャックすると、返される結果は応答オブジェクトになります。ここでの処理関数は、 target オブジェクトによって異なります (両方の関数がパラメーターとして渡されます)。
1. Object またはArray の処理関数はcollectionHandlers です。 2. Map 、 Set 、 WeakMap 、 WeakSet の処理関数はbaseHandlers です。 - 6. レスポンシブ オブジェクトをキャッシュの
reactiveMap に保存します。 key はtarget 、 value はproxy です。
mutableHandlers 処理関数
オブジェクトのプロパティにアクセスするとget 関数がトリガーされ、オブジェクトのプロパティを設定するとset 関数がトリガーされ、オブジェクトのプロパティを削除するとdeleteProperty 関数がトリガーされ、 in has 関数がトリガーされ、 getOwnPropertyNames によってownKeys 関数がトリガーされることがわかっています。次に、これらの関数のコード ロジックを見てみましょう。 関数を取得するパラメータが渡されないため、デフォルトではisReadonly とshallow 両方とも false になります。 
コードロジック: - 1.
__v_isReactive 属性が取得され、true が返された場合、ターゲットがすでにレスポンシブなオブジェクトであることを意味します。 - 2.
__v_isReadonly 属性を取得し、false を返します。(readonly は別のレスポンシブ API ですが、ここでは説明しません) - 3.
__v_raw 属性を取得し、ターゲット自体を返します。この属性は、ターゲットがすでにレスポンシブなオブジェクトであるかどうかを判断するために使用されます。 - 4. ターゲットが配列であり、includes、indexOf、lastIndexOfなどの属性にヒットした場合、配列のこれらの関数メソッドが実行され、配列の各要素に対してコレクション依存関係トラック(
arr 、 TrackOpTypes.GET 、 i + '')が実行され、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 のロジックは、間隔setupResult をinstance.setupState に割り当てることです。

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

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

- 非常に明確です。テンプレートをレンダリングするときに、
person 属性オブジェクトはctx から取得されますが、これは実際にはsetupState のperson 属性オブジェクトです。 setupState のperson 属性オブジェクトのname 、 age 、 address が取得されると、対応する値を取得するために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 コンポーネント レンダリング関数を定義し、次にこのomponentUpdateFn をReactiveEffect にカプセル化し、 ReactiveEffect オブジェクトのrun メソッドをコンポーネント オブジェクトのupdate プロパティに割り当て、次にupdate メソッドを実行します。このメソッドは、実際にはReactiveEffect オブジェクトのrun メソッドを実行します。

-
ReactiveEffect の run メソッドは渡された関数を保持し、現在のシーンはcomponentUpdateFn コンポーネント レンダリング関数であり、2 つのグローバル変数effectStack とactiveEffect 使用します。 - run メソッドを実行すると、まず
componentUpdateFn がactiveEffect に割り当てられ、 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 レスポンシブ機能の原理の詳細
|