Vue2、vue3 はオブジェクトの変更を監視します

1 応答原則

Vue の応答性はデータ双方向バインディングとも呼ばれます

MVVM モデル (Model-Viem-ViewModel)

  • DOM リスナー: ページとデータ間のバインディングを実現します。ページがデータを操作すると、それに応じて DOM とモデルが変更されます。
  • データ バインディング: データとページのバインディングを実現し、データが変更されたときにページを自動的にレンダリングします。

2 vue2 データ監視

2.1 実装原理

Vue は、object.defineProperty() を使用してデータ ハイジャックのためのデータ変更を検出し、依存関係の収集とビューの更新のためのパブリッシュ/サブスクライブ モデルを使用してデータ応答性を実装します。

object.defineProperty() メソッドは、オブジェクトの新しいプロパティを直接定義するか、オブジェクトの既存のプロパティを変更して、このオブジェクトを返します。

2.2 object.defineProperty() はデータを監視します

const obj = {
  name: "one",
  age: 18
}


Object.keys(obj).forEach(key => {
  let value = obj[key]

  Object.defineProperty(obj, key, {
    get: function() {
      console.log(`监听到obj对象的${key}属性被访问了`)
      return value
    },
    set: function(newValue) {
      console.log(`监听到obj对象的${key}属性被设置值`)
      value = newValue
    }
  })
})

obj.name = "two"
obj.age = 20

console.log(obj.name)   
console.log(obj.age)

obj.height = 1.88

2.3 object.defineProperty() の欠陥

1.definePropertyは特定のプロパティのみを監視でき、すべてのオブジェクトを監視することはできません。オブジェクトを監視するには、foreach、closure などのテクノロジを使用する必要があります。

2.defineproperty はオブジェクトのプロパティの追加および削除の操作を監視できません。

開発者は、対応するメソッド Vue.set()、Vue.delete を積極的に呼び出して更新する必要があります。

2.definepropertyは配列の追加と削除を監視できません

配列項目がインデックスインデックスを使用して直接設定されている場合、vue では検出されません。

Vue2.0では配列の応答を実現するために配列書き換え方式を採用しており、7つの方式はそれぞれ

  • 押す();

  • ポップ();

  • シフト();

  • シフト解除();

  • スプライス();

  • 選別();

  • 逆行する()

3 vue3 データ監視

3.1 原則 

Proxy オブジェクトは、基本的な操作のインターセプトとカスタマイズを実現するために、オブジェクトのプロキシを作成するために使用されます。後続の操作はすべて、元のオブジェクトではなく、プロキシに対する直接操作です。

const p = 新しいプロキシ(ターゲット、ハンドラー)

target Proxy ラッパーを使用する ターゲット オブジェクト (ネイティブ配列、関数、または別のプロキシなど、任意のタイプのオブジェクトにすることができます)。

handler 通常、属性として関数を持つオブジェクト。各属性の関数は、 p さまざまな操作を実行するときのエージェントの動作を定義します。

ハンドラオブジェクトのメソッド[MDN] (13トラップ)   

3.2 コード

const obj = {
  name: 'one',
  age: 18,
};

const objProxy = new Proxy(obj, {
  // 获取值时的捕获器
  get: function (target, key) {
    console.log(`监听到对象的${key}属性被访问了`, target);
    return target[key];
  },

  // 设置值时的捕获器
  set: function (target, key, newValue) {
    target[key] = newValue;
    console.log(`监听到对象的${key}属性被设置值`, target);
  },
  // 监听in的捕获器
  has: function (target, key) {
    console.log(`监听到对象的${key}属性in操作`, target);
    return key in target;
  },
  // 监听delete的捕获器
  deleteProperty: function (target, key) {
    delete target[key];
    console.log(`监听到对象的${key}属性delete操作`, target);
  },
});

console.log(objProxy.name);
console.log(objProxy.age);

objProxy.name = 'two';
objProxy.age = 20;

// in操作符
console.log('name' in objProxy);

// delete操作
delete objProxy.name;
console.log(obj.name);
console.log(obj.age);

 の結果

 

3.3 

おすすめ

転載: blog.csdn.net/m0_50789696/article/details/129420977