プロキシはVue3データの双方向バインディングの原理を実現します

プロキシはVue3データの双方向バインディングの原理を実現します

1. proxy と Object.defineProperty の利点

プロキシの利点:

  • プロキシはプロパティではなくオブジェクトを直接監視できます。
  • プロキシは配列の変更を直接監視できます。
  • Proxy には、apply、ownKeys、deleteProperty、has などに限定されず、Object.defineProperty では使用できない最大 13 個のインターセプト メソッドがあります。
  • Proxy は新しいオブジェクトを返します。目的を達成するには新しいオブジェクトに対してのみ操作できますが、Object.defineProperty はオブジェクトのプロパティを走査して直接変更することしかできません。
  • 新しい標準として、Proxy はブラウザ メーカーによる継続的なパフォーマンス最適化の焦点となり、これが新しい標準の伝説的なパフォーマンス ボーナスとなります。

Object.definePropertyの利点:

互換性良好: IE9 に対応していますが、Proxy にはブラウザ互換性の問題があり、ポリフィルで解消できないため、Vue の作者は、Proxy で書き直すには次のメジャーバージョン (3.0) まで待つ必要があると述べています。

2. プロキシ監視オブジェクトのシンプルな実装

1. プロキシオブジェクトのシンプルな実装

```javascript
let data = {}; // 空のオブジェクトを定義します。let proxy = new Proxy(data, {}); // Proxy を作成し、データをターゲット オブジェクトとして使用します。// Proxy プロキシ オブジェクトの名前属性を変更します。proxy.name = 'shelley';
console.log(プロキシ); 
コンソール.log(データ)
// { 名前: 'シェリー' }
// { 名前: 'シェリー' }

「」

2. 補足知識の反映

Reflectオブジェクトは、Proxy オブジェクトと同様に、オブジェクトを操作するために ES6 によって提供される新しい API です。

ターゲット オブジェクトに割り当てるには、 handler.set()で Reflect.set(... arguments ) を返す必要があります。

  • Reflect.set メソッドは、ターゲット オブジェクトの name プロパティを value と等しくなるように設定します。 name 属性が関数に設定されている場合、関数の this はレシーバーにバインドされます。
  • Reflect.get メソッドは、対象オブジェクトの name プロパティを検索して返します。そのようなプロパティが存在しない場合は、undefined を返します。

3. プロキシ方式

handler.set() メソッド属性は、操作のキャッチャーを設定します。

```javascript
データ = {
  名前: 'シェリー',
  年齢: '27'
};
p = new Proxy(data, {
  set(ターゲット、プロパティ、値) {
    // target = ターゲット オブジェクト // prop = 設定されたプロパティ // value = 変更された値 console.log(target, prop, value); // { name: 'shelley', age: '27' } age 18
    Reflect.set(...引数) を返します。
  }
})
ページ年齢 = 18;
console.log(data); // { 名前: 'shelley'、年齢: 18 }
「」

- handler.get() 属性読み取り操作のキャプチャ。

```javascript
データ = {
  名前: 'シェリー',
  年齢: 22
};
p = new Proxy(data, {
  get(ターゲット、プロパティ){
    console.log(target, prop); //{ name: 'shelley', age: 22 } 年齢
    Reflect.get(...引数) を返します。
  }
})
console.log(ページ番号);//22
「」

Object.defineProperty 監視オブジェクトのシンプルな実装

```javascript
var o = {}; // 新しいオブジェクトを作成します var bValue = 39; // アクセサー記述子プロパティのインスタンスをオブジェクトに追加します Object.defineProperty(o, 'bValue', {  
  // このコードは o のプロパティを設定せず、アクセスされたときにのみ get() を実行します {
    bValue を返します。
  },
  set(新しい値) {
    console.log('set==>', 新しい値);
    bValue = 新しい値;
  }
});
コンソールログ(o) // {}
// アクセサプロキシの bValue プロパティの get メソッドに入り、戻り、o オブジェクトの bValue の値を 38 に設定します。
console.log(o.bValue); // 38
// アクセサー プロキシの bValue プロパティの set メソッドに入り、bValue の新しい値を設定します。
// もう一度 get を入力して戻り、o オブジェクトの bValue の値を 40 に設定します。
o.b値 = 40;
コンソール.log(o.bValue) // 40
「」

まとめ:

  • es5 Object.definePropertyと比較すると、es6 の proxy はより強力で、多くのメソッドを提供し、メソッドをプロキシすることもできます。
  • Vue 3.0 はなぜ es6 プロキシを使用し、2.0 は使用しないのでしょうか? es6 は IE の下位バージョンなど一部のブラウザと互換性がないため、**ほとんどの主流ブラウザと互換性がある** 場合にのみ使用されます。

3. 手書きの vue3.0 双方向バインディング - es6 プロキシ

1. プロキシとは何か

  • プロキシは英語で「エージェント」を意味します。エージェントは、オブジェクトに直接作用するのではなく、何かを取得したり、特定の操作を実行したりするために使用する仲介者です。
  • プロキシは、ターゲット オブジェクトの前にインターセプション レイヤーを設定することと理解できます。オブジェクトへの外部アクセスはすべて、まずこのインターセプション レイヤーを通過する必要があるため、外部アクセスをインターセプトまたはフィルターするメカニズムが提供されます。

2. vue.jsで双方向バインディングを使用する

```javascript
<div id="アプリ">
  <h2>{{メッセージ}}</h2>
  <input type="text" v-model="msg"/>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<スクリプト>
  vm = new Vue({
  el: '#app',
  データ: {
    メッセージ: 'シェリー'
},
})
</スクリプト>


「」

プロキシと Object.defineProperty

Vue 2.0 での双方向バインディング、双方向バインディングに Object.defineProperty() を使用する

欠点:

  • 配列を監視することはできませんが、配列メソッド (push、pop、shift、unshift など) を書き換えることはできます。双方向バインディングとデータ監視を実行します
  • 主に複数層のデータに対する 1 回限りの再帰操作が原因で、効率が低下します。データが大きい場合や深い場合は、パフォーマンスが非常に低下します。
  • 制限により、新しく追加/削除されたデータを監視することはできません。そのため、vue2.0 では手動で追加するために $set が使用されます。

- Object.definePorperty() はすべてのオブジェクトのすべてのプロパティを再帰的に走査するため、データ階層が深い場合はパフォーマンスに影響します。

- Object.definePorperty() はオブジェクトに対してのみ使用でき、配列に対しては使用できません。

- Object.definePorperty() は定義中のプロパティのみを監視でき、新しく追加されたプロパティは監視できません。

- Object.definePorperty() は配列では使用できないため、vue2.0 では配列メソッドのプロトタイプを書き換えて配列データを監視することを選択しますが、それでも配列のインデックスと長さの変更を監視することはできません。

Vue 3.0 での双方向バインディング、双方向バインディングに Proxy と Reflect を使用する

アドバンテージ:

  • プロキシは配列とオブジェクトを傍受して監視できる

欠点:

  • プロキシは複数のset/get応答をトリガーします

解決:

  • debounceと同様の操作を使用して、値が一度だけ応答するように最適化する
  • ② (vue3.0での解決法) キーがターゲット自身の属性であるかどうか、値がターゲット[キー]と等しいかどうかを判定することで、冗長なset/get操作を回避できる

プロキシは1つのレイヤーしかプロキシできず、深く監視することはできない

  • ① 深い再帰を使用して各レイヤーを監視します。 Reflect.get() をうまく使用すると、オブジェクト (次のレイヤー) の内部構造のプロパティが返され、次のレイヤーがまだオブジェクトであるかどうかが判断され、深い再帰操作が使用されます。しかし、それはパフォーマンスに大きな影響を与えます
  • ②weakMapを使用し、2つのweakMapを使用してオリジナルデータとレスポンシブデータを保存します。データにアクセスする際は保存されたデータから検索し、見つからない場合はプロキシ操作を実行します。

これで、Vue3 データ双方向バインディングのプロキシ実装の原理に関するこの記事は終了です。Vue3 データ双方向バインディングのプロキシ実装に関するより関連性の高いコンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • Vue3はクロスドメイン問題を解決するためにプロキシを設定します
  • Vue3でプロキシパッケージデータを取得する方法
  • Vue3 のプロキシの簡単な実装の詳細説明 プロキシの例
  • Vue3 がデータ監視を実装するためにプロキシを使用する理由の分析
  • Vue3 のプロキシの基本的な使用方法

<<:  Ubuntu環境にAnaconda3をインストールするための完全な手順

>>:  ブラウザ(IEシリーズ)を判別するための条件付きコメント

推薦する

不規則な絵の滝の流れ原理の分析と応用

プロジェクトで発生した不規則な絵画壁のレイアウト問題は、次のように分析されます。 1.img dis...

Vueデータ変更検出の基本的な実装の簡単な分析

目次1. オブジェクトの変更検出2. オブジェクトに関する質問配列変更検出3.1 背景3.2 実装I...

MySQL データベースは SQL ステートメントを知っている必要があります (拡張バージョン)

拡張版です。質問とSQL文は以下の通りです。ユーザー テーブルを作成し、id、name、gender...

Linux システムに docker をインストールし、ssh 経由で docker コンテナにログインする方法

注: 私はCentosを使ってdockerをインストールしていますステップ1: Dockerをインス...

Linux ログ内のキーワードとその前後の情報を検索する方法の例

日常業務では、ログを表示する必要がよくあります。たとえば、 tail コマンドを使用してログをリアル...

HTML シンプルな Web フォーム作成例の紹介

<input> はユーザー情報を収集するために使用され、終了ステートメントはありません。...

Mac 向け MySQL 5.7.17 のインストールと設定のチュートリアル

1. MySQLをダウンロードする公式サイトのダウンロードページをクリックすると次のページに入ります...

CSS フロントエンドページレンダリング最適化属性 will-change の具体的な使用法

序文スクロールやサイズ変更などのスクロール イベントがトリガーされると、トリガーの頻度が非常に高くな...

docker を使用して Spring Boot をデプロイし、Skywalking に接続する方法

目次1. 概要1. スカイウォーキング入門2. スカイウォーキング建築3. スカイウォーキングはどの...

ホバードロップダウンメニューを実装するためのネイティブJS

JS はホバー ドロップダウン メニューを実装します。これは、フロントエンドの面接で遭遇するシナリ...

Docker で MySQL マスター スレーブ レプリケーションを実装するためのサンプル コード

目次1. 概要1. 原則2. 実装3. スレーブインスタンスを作成する4. マスタースレーブ構成要約...

MySQL (InnoDB) がデッドロックを処理する方法の詳細な説明

1. デッドロックとは何ですか?正式な定義は次のとおりです: 2 つのトランザクションが相手側で必要...

border-image を使用してテキストバブルの境界線を実装する方法のサンプルコード

開発中に、非常に単純なテキストバブル効果に遭遇しました。これは、おおよそ次のようになります。 うーん...

タオバオモールのホームページ上の大きな画像のデザイン構造に関する分析と意見(写真)

前回、Taobaoの詳細ページを分析した後(クリックして表示)、ショッピングモールの基本テンプレート...

Excel エクスポートは docker 環境では常に失敗する

Excel のエクスポートは、docker 環境では常に失敗します。最も直接的な原因は、中国語フォン...