Vue.setの使用と原則(ソースコードシリーズの分析)

分析ソースコードシリーズ-Vue.set /vm.$set詳細

機能と概念の説明

公式文書:Vue-set

レスポンシブオブジェクトにプロパティを追加し、この新しいプロパティもレスポンシブであり、ビューの更新をトリガーすることを確認します。Vueは通常の新しいプロパティ(this.myObject.newProperty = 'hi'など)を検出できないため、リアクティブオブジェクトに新しいプロパティを追加するために使用する必要があります。

制限事項
ルートレベルのレスポンシブ属性を動的に追加することは許可されていません。といった:

// 错误写法
this.$set(this, 'newkey', 1111)

// 正确写法
this.$set(this.obj, 'newkey', 111)

// 取值: this.obj.newkey => 111

概要

  • Vue.setそして、vm.$set方法は実際には同じですが、言い回しは同じではありません
  • その効果は、ページに属性を動的に追加することであり、動的に追加された属性も応答属性です。

レスポンシブ属性を追加するためにsetを使用する理由

VUE応答性の原則を見て:原則を結合双方向のデータはVUE
実際に見ることができますが、応答に依存しているObject.defineProperty
Object.defineProperty複数のプロパティがある場合にだけ、オブジェクトの属性のいずれかに聞く必要があります

理解するためにデモを見てください:

var data = {
    
    }

Object.defineProperty(data, 'data1', {
    
    
  get: function() {
    
    
    console.log('get data1')
    return this.value
  },
  set: function(newVal) {
    
    
    console.log('set data1')
    this.value = newVal
  }
})

data.data1 = 111 // 将会打印 set data1
console.log(data.data1) // 先打印 get data1  然后才是 111

data.data2 = 222 // 无打印,无报错
console.log(data.data2) // 直接打印222。表示没有进过 `Object.defineProperty`

ソースコードを見始める

これがデバッグ用のデモです

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
  var app = new Vue({
     
     
    el: '#app',
    data: {
     
     
      addData: {
     
     }
    }
  })
  debugger
  app.$set(app.addData, 'newkey', 1111)
</script>

$set当時メソッドを最初に入力し、最初にデフォルト値のセクションに来ました。今回はnull値を返します。戻った後、再入力$setはデバッグする必要がある部分です。

デバッグモードで、setメソッドを入力します

2行目1081は、ターゲットノードのデータ型を検出するための方法、つまり$set最初のパラメータの検出です。

  • 1085-1089は配列のタイプを決定します。結局のところ、特殊なタイプObject.defindPropetyは配列の変更を検出できないため、配列の変更は手動で更新されます。
  • 1090-1093は、属性が以前にすでに存在しているかどうかを判断するためのものであり、存在する場合は監視を繰り返す必要はありません。
  • 1095--1100は、ルートノードをthis.dataデータに直接追加できないことを確認するためのものです
  • ob略して1094行変数が観測される(オブザーバー)ことに注意してくださいまた、変数が監視されているかどうかを判断するためにも使用されます
  • 監視されており、繰り返し監視する必要がない値は、対応する値に直接返されますvalまた$set、現在の戻り値を返します
  • オブジェクトが新しい場合は、1106行defineReactive$$1メソッドに進みます

リスナーdefineReactive$$1メソッドを追加する

  • 1021new Dep ビューの初期化deplookの分析dep分析が必要です。これには、次のプロセスの多くが含まれます。csdnはハッシュナビゲーションをサポートしていないため、手動で下にスライドして確認する必要があります〜
  • 1023-1026オブジェクトが読み取り可能および書き込み可能かどうかを判別します
  • 1019--1033ターゲットオブジェクトgetsetメソッドを取得します
  • 1035前のコードに浅い変数がありますが、この変数は存在!shallowません。これは本当です。したがって、観察分析csdnを表示するobserveメソッドの実装は、ハッシュナビゲーションをサポートしていません。表示するには、手動で下にスライドする必要があります。
  • 上記のobserve分析を読んだ後、私たちobserveは彼の息子、サイクリングの特性がリスニングを追加することを知っています。
  • 1039行目は、属性値を取得するイベントにバインドされています。対応する値を取得するとき、私Dep.targetはそれをグローバルオブザーバーとして見ましたwatchしたがって、継承さメソッドからdep.targetの現在のdependメソッドのターゲット呼び出された場合Depこれは、イベントを監視するためのコールバックを登録することと同じです(これは推定さwatchcomputed、前兆が埋もれています)
  • 1052スタートラインset方式。またgetter、内部の現在の値を取得するために独自開始します
  • 1069行目、オブジェクトを新たにコピーする場合、ループ内でこれらのオブジェクトのデータ保持を再度追加する必要があります。既に保持されている場合は、スキップできます。これは上記のコードです。
  • 最後の1070行は、setの後に呼び出されdep.notify()ます。対応するオブジェクトの更新をトリガーする必要がある時間を格納します(サブスクリプションオブザーバーモード)。値が更新されたので、関連するサブスクリプション関数に対してトリガーされます(この時点でウォッチもトリガーされ、ビューもこの時点で更新されます)そして、フロントの前に設定値を取得する必要があるので、watch内部メソッドnewValoldValはこの時点で記録されています
  • 最後に、現在の値が返され、$setメソッドの実行が終了します。



dep分析

depコードはそれほど長くありません。depはサブスクリプションセンターに相当します

  • 717行目では、各部門に対応するIDがあり、自己増加していることがわかります。
  • 718行目はイベントセンターと見なすことができ、すべての監視はここに保存されます
  • depプロトタイプにはいくつかのメソッドがあることがわかりaddSub removeSub depend notifyます。これらはすべて、対応するモニターの操作、追加/削除、対応する依存関係の検索、およびこれらのメソッドへの通知に使用されます。
  • 725行にDep.targetは非常に詳細なメモがあり、グローバルにユニークなビューア

コアはいくつかのaddSub removeSub depend notify方法を覚えていることです。次に、今すぐコードを確認し続けます

分析を観察する

特に思いやりのあるメモ

以下のためのオブザーバのインスタンスを作成しようとする値、
オブザーバインスタンスの値を作成しようと
成功し、観察した場合に戻り、新たな観測者を
首尾よく観察している場合、新しい視聴者が返され
たり、既存の観測値がすでにあればいずれかを持っています。
あるいは、既存のオブザーバー(値にすでに1つ含まれている場合)

  • それはそうですvalue.__ob__、このプロパティは、観察されているだろう、がある場合、これは私たちである$setとの判断の最初のステップ__ob__

  • 次に、配列を区別します。配列にはオブザーバーがありません

  • 主に1003の線を表示するnew Observeには、現在のオブジェクトではなく、首都に注意する新しいオブザーバーを作成します

  • new Observe 下の図2では、個別に説明しません。

  • 926行。__ob__プロパティ追加するには、間違いなく、__ob__列挙できないタイプに設定してください。詳細については、926に入るコードを見ることができます

  • 927-933はすべて配列操作用です

  • 行935、現在のオブジェクトのwalkメソッド。コードを直接貼り付けると、それがループであり、オブジェクトを1回トラバースし、オブジェクトごとに呼び出すことがわかりますdefineReactive$$1ご覧のとおり、このメソッドは、値がオブジェクトタイプの場合にのみ呼び出されます。

  • と呼ばれてdefineReactive$$1いるので次に、ここで再帰が形成されます。再帰の先頭は、属性がオブジェクトでなくなったときに呼び出しを停止することdefineReactive$$1です。

  • これを見た後、次のステップに戻って、defineReactive $$の1035行をリッスンするメソッドを追加する必要があります

/**
 * Walk through all properties and convert them into
 * getter/setters. This method should only be called when
 * value type is Object.
 */
Observer.prototype.walk = function walk(obj) {
    
    
  var keys = Object.keys(obj)
  for (var i = 0; i < keys.length; i++) {
    
    
    defineReactive$$1(obj, keys[i])
  }
}

総括する

  • vueレスポンシブの原則は、これら2つのメソッドのメソッドメソッドにそれぞれ依存しObject.defindPropety、対応するイベントをトリガーしますgetset

  • JSとObject.defindPropety動的に追加できない制限のため、プロパティを監視する必要があるため、Vue.set()このメソッドを使用する必要があります

  • Vue.set()メソッドの内部は循環処理プロセスです。現在の新しいモニターがオブジェクトの場合、最後のサブ属性数组/非对象类型パラメーターになるまで、それ自体を呼び出して再帰を形成し続け、再帰が終了してから、あなた自身、モニターでそれは他の関連するメソッドをトリガーします(Depでサブスクライブされたイベントがトリガーされます)。一般的な双方向データバインディングを形成する

  • 以来Object.defindPropety変更は唯一の配列の変更内の特定のインデックスの値がそのように使用しなければならない、を聞いていないので、オブジェクト、監視することができVue.set、手動で更新をトリガにし、この時間は、Vue.set唯一の更新された値を行い、新規増加の監視を繰り返すことはしません

最初の元の記事:ソースコードシリーズの分析-Vue.set /vm.$set詳細な説明これは新しいブログアドレスです。興味があればご覧ください。

おすすめ

転載: blog.csdn.net/Jioho_chen/article/details/107005845