Vue2 および Vue3 の応答原理の実装の中核

Vue の概要

Vue.js は、主にユーザー インターフェイスとシングル ページ アプリケーション (SPA) の構築に使用されるオープンソースのプログレッシブ JavaScript フロントエンド フレームワークです。Vue.js は他のライブラリや既存のプロジェクトと簡単に統合でき、応答性の高いデータ駆動型の最新の Web アプリケーションを開発する効果的な方法と考えられています。

Vue.js のコア機能:

  1. 応答性の高いデータ バインディング: Vue.js は、データの双方向バインディングを通じてユーザー入力やページ変更に応答できます。
  2. コンポーネント化: Vue.js を使用すると、開発者は単一のコンポーネントを、優れたパフォーマンスを備え、再利用できる独立したモジュールに変換できます。
  3. テンプレートベースの構文: Vue.js は、開発者が HTML テンプレートを簡単に作成して Vue.js コンポーネントにバインドできるテンプレート構文を提供します。

Vue2 の応答原理

Vue2 の応答原理は、オブジェクトのプロパティを定義してハイジャックできる ES5Object.defineProperty()に、プロパティ値が変更されると、Vue は変更を検出し、対応するページ コンテンツを再レンダリングできます。

具体的な実装原則は次のとおりです。

  1. Vue の初期化フェーズでは、Vue は受信dataオブジェクトを、dataオブジェクトのすべてのプロパティをgetter/setterform。
  2. ページでデータが使用されると、Vue は property にアクセスしてgetter関数、Watcher現在のプロパティの依存関係に現在の (オブザーバー) オブジェクトを追加します。
  3. データが変更されると、Vue はリスナーを通じて変更を検出し、対応する property のsetter関数これにより、プロパティの下のすべての依存関係Watcherが更新されるように通知されます。
  4. Watcherオブジェクトが通知されると、対応するコンポーネントにメッセージを送信して、ページ全体を更新するためにビューを再レンダリングする必要があることを通知します。

Vue2 はオブジェクト プロパティの変更のみを監視でき、オブジェクト プロパティや配列メソッドの追加/削除の変更は監視できないことに注意してください。そのため、 Vue.set()orVue.delete()push()、、、、、メソッドなど、配列を操作pop()ます。splice()shift()unshift()

Vue2 データハイジャックのサンプルコードは次のとおりです。

const data = {
    
     msg: 'Hello Vue' }

Object.defineProperty(data, 'msg', {
    
    
  get() {
    
    
    console.log('get');
    return val;
  },
  set(newValue) {
    
    
    console.log('set', newValue);
    val = newValue;
  }
})

Object.defineProperty()の詳細説明

Object.defineProperty() は ES5 の新しいメソッドで、オブジェクトの新しいプロパティを定義したり、オブジェクトのプロパティを変更したりするために使用されます。その構文は次のとおりです。

Object.defineProperty(obj, prop, descriptor)

パラメータの意味:

  • obj: プロパティを定義するオブジェクト。
  • prop: 定義または変更するプロパティの名前。
  • descriptor: 定義または変更する必要がある属性記述子オブジェクト。

プロパティ記述子オブジェクトには、次のオプションのプロパティが含まれます。

  • value: 属性の値。デフォルトでは未定義です。
  • writable: true の場合、プロパティの値は代入演算子によって変更できます。デフォルトは false です。
  • enumerable: true の場合、オブジェクトのプロパティを列挙するときにプロパティを列挙できます。デフォルトは false です。
  • 構成可能: true の場合、Object.defineProperty() メソッドを使用してプロパティの記述子を変更できます。デフォルトは false です。
  • get: 属性の読み取りメソッド。
  • set: 属性の割り当てメソッド。

Object.defineProperty() の欠点

  • 配列の変更を監視できません。元の配列
    Vue2を変更するメソッドを突然変異メソッドとして定義してください。etcなどの突然変異メソッドはトリガーできませんetc.などの非突然変異メソッドは、元の配列を変更しませんが、新しい配列を返します。最善のアプローチは、配列の変更を監視するためにこれらの突然変異メソッドを書き直すことです。
    push、pop、shift、unshift、splice、sort、reverseset
    filter,concat,slice
    Vue2
  • オブジェクトの各プロパティをトラバースする必要があり、ほとんどの
    場合、連携してトラバースする必要があるため、追加のネスト層が存在します。また、トラバーサルのため、オブジェクトの特定のプロパティを「ハイジャック」する必要がない場合でも、この時点では「ハイジャック」が追加されます。Object.definePropertyObject.keys
  • ネストされたオブジェクトは深くトラバースする必要がある
    オブジェクトが深くネストされている場合は、各オブジェクトの各プロパティが呼び出されるObject.defineProperty()まで、。

Vue3 の応答原理

Vue3 の応答原理では、より効率的かつ強力なデータ ハイジャックと応答性を実現するために、主に Vue2 ではProxyなく。Object.defineProperty()

プロキシ オブジェクトは、アクセス データや変更データを傍受することでデータ ハイジャックを実装できます。Reflect オブジェクトは、より柔軟で使いやすいデータ操作メソッドを提供します。たとえば、Reflect.has() を使用してオブジェクトに特定のプロパティがあるかどうかを確認したり、Object.defineProperty() の代わりに Reflect.defineProperty() を使用したりできます。 )。

具体的な実装原則は次のとおりです。

  1. Vue3 の初期化フェーズでは、Vue3は オブジェクト (つまり use )を使用してdata受信オブジェクトをプロキシします。ここでプロキシされるオブジェクト、 はプロキシでの。Proxynew Proxy(target, handler)targethandlertarget

  2. データがページで使用されると、Vue3 はget操作を、プロキシ オブジェクトhandler.get()が呼び出され、操作をhandlerキャプチャ、Watcher現在の (オブザーバー) オブジェクトを現在のプロパティの依存関係に追加します。

  3. データが変更されると、Vue3 はリスナーを通じて変更を検出し、 data に対応するset操作プロキシ オブジェクトhandler.set()が呼び出されます。これにより、プロパティの下にあるすべての依存する 'Watcher' オブジェクトに更新するよう通知します。

  4. Watcherオブジェクトが通知されると、対応するコンポーネントにメッセージを送信して、ページ全体を更新するためにビューを再レンダリングする必要があることを通知します。

Vue3 で Proxy オブジェクトを使用してデータ応答性を実装するコードは次のとおりです。

const data = {
    
     msg: 'Hello Vue' }

const reactiveData = new Proxy(data, {
    
    
  get(target, key) {
    
    
    console.log('get');
    return target[key];
  },
  set(target, key, value) {
    
    
    console.log('set');
    target[key] = value;
    return true;
  }
})

上記のコードでは、dataオブジェクトは Proxy オブジェクトを通じてプロキシされreactiveDataますreactiveData。オブジェクトのプロパティにアクセスするときは、Proxy オブジェクト内の get() 関数が呼び出されます。プロパティを設定するときは、Proxy オブジェクト内の set() 関数が呼び出されます。 。get() 関数と set() 関数では、属性の読み取りと割り当てをインターセプトすることができ、データの応答性を実現します。

詳細なプロキシ

プロキシは、ES6 で追加された新しいオブジェクトです。別のオブジェクトをプロキシし、オブジェクトのプロパティの読み取り、割り当て、定義などの一連の操作をインターセプトするために使用されます。その構文は次のとおりです:

new Proxy(target, handler)

プロキシのパラメータ:

  • target: プロキシされるターゲット オブジェクト。
  • handler: プロパティがフック関数 (トラップ) であるオブジェクト。プロキシ オブジェクトの操作をインターセプトするために使用されます。

ハンドラーには、次のオプションのフック関数 (トラップ) が含まれています。

  • get(target, prop): オブジェクトの読み取り操作をインターセプトするために使用されます。
  • set(target, prop, value): オブジェクトの代入操作をインターセプトするために使用されます。
  • has(target, prop): in 操作をインターセプトするために使用されます。
  • deleteProperty(target, prop): 削除操作をインターセプトするために使用されます。
  • apply(target, thisArg, args): 関数呼び出しをインターセプトするために使用されます。
  • construct(target, args): 新しい操作をインターセプトするために使用されます。

プロキシの利点

  • Proxyプロパティの代わりにオブジェクトを直接監視できます。
  • Proxyアレイの変更を直接監視できます。
  • Proxy返されるのは新しいオブジェクトです。目的を達成するために新しいオブジェクトを操作することしかできませんが、Object.definePropertyオブジェクトのプロパティを走査して直接変更することしかできません。

おすすめ

転載: blog.csdn.net/w137160164/article/details/131059943