深いvue応答式の原理(day 03)

2758 ワード

VUEがどのように変化を追跡するか
通常のJavaScriptオブジェクトをdataオプションとしてVueインスタンスに転送すると、Vueはこのオブジェクトのすべてのpropertyを遍歴し、Objectを使用します.definePropertyはこれらのpropertyをすべてgetter/setterに変換します.Object.definePropertyはES 5のshimできない特性であり、VueがIE 8以下のブラウザをサポートしていない理由である.
これらのgetter/setterはユーザには見えませんが、内部ではVueが依存を追跡することができ、propertyがアクセスされ、変更されたときに変更を通知します.ここで注意しなければならないのは、異なるブラウザがコンソールでデータオブジェクトを印刷する際のgetter/setterのフォーマットが異なるため、vue-devtoolsをインストールして、検査データにより友好的なユーザーインタフェースを取得することをお勧めします.
各コンポーネントインスタンスはwatcherインスタンスに対応し、コンポーネントレンダリング中に「接触」したデータpropertyを依存として記録します.その後、依存項目のsetterがトリガーされるとwatcherに通知され、関連付けられたコンポーネントが再レンダリングされます.
変化を検出するための注意事項
JavaScriptの制限により、Vueは配列やオブジェクトの変化を検出できません.それでも、これらの制限を回避し、応答性を保証する方法があります.
オブジェクトの場合
すでに作成されたインスタンスの場合、Vueはルート・レベルのレスポンス・プロパティを動的に追加できません.ただし、Vueは使用可能である.set(object,propertyName,value)メソッドは、ネストされたオブジェクトに応答式propertyを追加します.たとえば、
Vue.set(vm.someObject, 'b', 2)

vm.$も使用できます.setインスタンスメソッド、これもグローバルVueである.setメソッドの別名:
this.$set(this.someObject,'b',2)

Objectを使用するなど、既存のオブジェクトに複数の新しいpropertyを割り当てる必要がある場合があります.assign()または_.extend().ただし、このようにオブジェクトに追加された新しいpropertyは更新をトリガーしません.この場合、元のオブジェクトとブレンドするオブジェクトのpropertyを使用して新しいオブジェクトを作成する必要があります.
配列の場合
Vueは次の配列の変動を検出できません.
  • インデックスを使用して配列項目を直接設定する場合、例えばvm.items[indexOfItem] = newValue
  • 配列の長さを変更すると、例えばvm.items.length = newLength

  • 第1の問題を解決するために、以下の2つの方法はvmと実現することができる.items[indexOfItem]=newValueは同じ効果で、応答システム内でステータス更新をトリガーします.
    // Vue.set
    Vue.set(vm.items, indexOfItem, newValue
    // Array.prototype.splice
    vm.items.splice(indexOfItem, 1, newValue)
    

    応答性propertyの宣言
    Vueでは、ルート応答式propertyを動的に追加できないため、インスタンスを初期化する前に、空の値であってもすべてのルート応答式propertyを宣言する必要があります.
          data       message,Vue                    property。
                    ,                    ,   Vue                 。
                           :data             (schema)。           property,                            。
    

    非同期更新キュー
    まだ気づいていないかもしれませんが、VueはDOMを更新するときに非同期で実行されます.データの変化が検出されると、Vueはキューを開き、同じイベントサイクルで発生したすべてのデータ変更をバッファリングします.同じwatcherが複数回トリガーされると、キューに1回のみプッシュされます.このようなバッファリング時の重複データの除去は,不要な計算やDOM動作を回避するために非常に重要である.次に、次のイベントループ「tick」で、Vueはキューをリフレッシュし、実際の(重複した)作業を実行します.Vueは内部で非同期キューに対してオリジナルのPromiseを使用しようとする.then、MutationObserver、setImmediateは、実行環境がサポートされていない場合、setTimeout(fn,0)の代わりに使用されます.
    例えばvmを設定するとsomeData='new value'で、このコンポーネントはすぐに再レンダリングされません.キューがリフレッシュされると、コンポーネントは次のイベントループ「tick」で更新されます.多くの場合、このプロセスに関心を持つ必要はありませんが、更新後のDOM状態に基づいて何かをしたい場合は、少し難しいかもしれません.Vuejsは通常、開発者がDOMに直接接触しないように「データ駆動」で考えることを奨励していますが、時にはそうしなければなりません.データが変化する後にVueの更新DOMが完了するのを待つために、データが変化する直後にVueを使用することができる.nextTick(callback).これにより、コールバック関数はDOM更新が完了した後に呼び出されます.