ホームページ  >  記事  >  ウェブフロントエンド  >  Vue の応答性の原則についての深い理解

Vue の応答性の原則についての深い理解

青灯夜游
青灯夜游転載
2020-10-12 17:33:581843ブラウズ

Vue の応答性の原則についての深い理解

Vue の最も注目すべき機能の 1 つは、目立たない反応性システムです。モデル層 (モデル) は通常の JS オブジェクトであり、これを変更するとビュー (ビュー) が更新されます。これにより、状態管理が非常にシンプルかつ直観的になりますが、いくつかの一般的な問題を回避するには、状態管理がどのように機能するかを理解することが重要です。

この記事では、Vue 応答システムの基礎となる詳細を詳しく紹介します。

変更の追跡

通常の JS オブジェクトを Vue インスタンスの data オプションに渡します。Vue はこのオブジェクトのすべてのプロパティを走査し、 use Object.defineProperty は、これらすべてのプロパティをゲッター/セッターに変換します。

Object.defineProperty は ES5 でのみサポートされており、シムを適用することはできません。これが、Vue が IE8 ブラウザーをサポートしない理由です。

ゲッター/セッターはユーザーには表示されませんが、内部的には Vue が依存関係を追跡し、プロパティがアクセスおよび変更されたときに変更を通知することができます。

各コンポーネント インスタンスには、対応するウォッチャー インスタンス オブジェクトがあります。コンポーネントのレンダリング中にプロパティを依存関係として記録し、依存関係のセッターが呼び出されたときに再計算するようにウォッチャーに通知し、関連するコンポーネントが更新されます。

Vue の応答性の原則についての深い理解

変更検出

最新の JS の制限 (および Object.observe の非推奨) のため)、Vue ではオブジェクト プロパティの追加または削除が検出されません。 Vue はインスタンスの初期化時に属性のゲッター/セッター変換プロセスを実行するため、Vue が応答できるように属性を変換するには、その属性がデータ オブジェクトに存在する必要があります。

var vm = new Vue({
  data:{
    a:1
  }
})
// `vm.a` 是响应的
vm.b = 2
// `vm.b` 是非响应的

Vue では、既に作成されたインスタンスに新しいルートレベルのリアクティブ プロパティを動的に追加することはできません。ただし、Vue.set(object, key, value) メソッドを使用して、ネストされたオブジェクトに応答プロパティを追加することは可能です。

Vue.set(vm.someObject, 'b', 2)

グローバル Vue.set メソッドのエイリアスでもある vm.$set インスタンス メソッドを使用することもできます。

this.$set(this.someObject,'b',2)

Object.assign() メソッドや _.extend() メソッドを使用して属性を追加するなど、既存のオブジェクトに属性を追加したい場合があります。ただし、オブジェクトに追加された新しいプロパティは更新をトリガーしません。この場合、元のオブジェクトのプロパティと新しいプロパティを含む新しいオブジェクトを作成できます。

// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })`
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })

リアクティブ プロパティの宣言

Vue ではルート レベルのリアクティブ プロパティを動的に追加できないため、初期化する前にルート レベルを宣言する必要があります。インスタンスの Reactive プロパティ (null 値のみの場合も含む)。

var vm = new Vue({
  data: {
    // 声明 message 为一个空值字符串
    message: ''
  },
  template: &#39;<div>{{ message }}</div>&#39;
})
// 之后设置 `message` 
vm.message = &#39;Hello!&#39;

message が data オプションで宣言されていない場合、Vue はアクセスしようとしているプロパティが存在しないことをレンダリング関数に警告します。

このような制限の背後には技術的な理由があり、依存関係追跡システムの特殊なケースを排除し、型チェック システムの助けを借りて Vue インスタンスをより効率的に実行できるようにします。

そして、コードの保守性の観点からも重要な考慮事項があります。データ オブジェクトはコンポーネントの状態の概要のようなもので、すべてのリアクティブ プロパティを事前に宣言することで、コンポーネント コードを後で再読み込みしたり、読み取ったりすることができます。他の開発者によるもので、理解しやすくなっています。

非同期更新キュー

Vue は DOM 更新を非同期で実行します。データ変更が観察される限り、Vue はキューを開き、同じイベント ループ内で発生するすべてのデータ変更をバッファーに入れます。同じウォッチャーが複数回トリガーされた場合、キューにプッシュされるのは 1 回だけです。

バッファリング中のこの種の重複排除は、不必要な計算や DOM 操作を回避するために非常に重要です。次に、次のイベント ループ「ティック」で、Vue はキューをフラッシュし、実際の (重複排除された) 作業を実行します。

Vue は内部的に非同期キューにネイティブの Promise.then と MutationObserver を使用しようとします。実行環境がそれをサポートしていない場合は、代わりに setTimeout(fn, 0) が使用されます。

例: vm.someData ='新しい値' を設定すると、コンポーネントはすぐには再レンダリングされません。キューがフラッシュされると、イベント ループ キューがクリアされる次の「ティック」でコンポーネントが更新されます。ほとんどの場合、このプロセスについて心配する必要はありませんが、DOM 状態が更新された後に何かをしたい場合は、少し注意が必要になることがあります。

Vue.js は一般に、開発者が「データ駆動型」の方法で考え、DOM との直接の接触を避けることを推奨していますが、そうすることが必要な場合もあります。データ変更後に Vue が DOM の更新を完了するのを待つために、データ変更直後に Vue.nextTick(callback) を使用できます。このコールバック関数は、DOM の更新が完了した後に呼び出されます。

<div id="example">{{message}}</div>
var vm = new Vue({
  el: &#39;#example&#39;,
  data: {
    message: &#39;123&#39;
  }
})
vm.message = &#39;new message&#39; // 更改数据
vm.$el.textContent === &#39;new message&#39; // false
Vue.nextTick(function () {
  vm.$el.textContent === &#39;new message&#39; // true
})

vm.$nextTick() インスタンス メソッドをコンポーネント内で使用すると、グローバル Vue が必要なく、コールバック関数内のこれが現在の Vue インスタンスに自動的にバインドされるため、特に便利です。 ##

Vue.component(&#39;example&#39;, {
  template: &#39;<span>{{ message }}</span>&#39;,
  data: function () {
    return {
      message: &#39;没有更新&#39;
    }
  },
  methods: {
    updateMessage: function () {
      this.message = &#39;更新完成&#39;
      console.log(this.$el.textContent) // => &#39;没有更新&#39;
      this.$nextTick(function () {
        console.log(this.$el.textContent) // => &#39;更新完成&#39;
      })
    }
  }
})

関連する推奨事項:


2020 フロントエンド vue インタビューの質問の概要 (回答付き)

vueチュートリアルの推奨事項: 2020 年最新の vue.js ビデオ チュートリアル 5 選

プログラミング関連の知識について詳しくは、プログラミング入門をご覧ください。 !

以上がVue の応答性の原則についての深い理解の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。