Vueで配列の変更を監視する方法

Vueで配列の変更を監視する方法

序文

以前、Vue におけるレスポンシブ データの原則について学びました (そして、Vue のレスポンシブ原則についてメモを取りました)。実際には、Object.defineProperty を通じてゲッターとセッターを制御し、オブザーバー モードを使用するレスポンシブ デザインです。次に、配列には一連の操作メソッドがありますが、配列のゲッター メソッドとセッター メソッドはトリガーされません。では、配列のレスポンシブ デザインは Vue でどのように実装されるのでしょうか? 一緒に学んでみましょう。

ソースコード

https://github.com/vuejs/vue/blob/dev/src/core/observer/array.js

学習の第一歩はどこから始めればよいでしょうか?

うーん...
まず、Vue でのデータ応答性の原則を明確にして、Vue で配列の変更を検出する方法を理解しやすくする必要があると思います。そのため、オンラインで記事を見つけて、ソースコードとともに読むことができます。理解できると思います。以前読んだブログと、それを読んだ後に書いた学習記録をオススメします(笑)。

Vue レスポンシブ原則

Vue における双方向バインディングの原理と実装

さて、まずはこれを見てみましょう。ハハハ!

写真から始めましょう

下の図を見て、まずは Vue での実装の考え方を理解しましょう。そうすれば、後でソースコードの実装を見たときに、明確で理解しやすいものになります。

この絵を見て考えてみてください。大体理解できましたか?

まずブラウザが__proto__ポインタをサポートしているかどうかを確認します

配列のこれらの 7 つのメソッドを書き換え、__proto__ がサポートされているかどうかに応じて、書き換えた配列を配列のプロトタイプにポイントします。

簡単じゃないですか! ! !

ソースコードを見る

実装の原理がわかったところで、ソースコードを見てみましょう。ソースコードを見る主な目的は、作者がどのように実装したかをより深く理解することです。また、優れたコードエンコード方法を見て、そこから学ぶこともできます。

下のコードブロックにいくつか説明を書いておきました。

//https://github.com/vuejs/vue/blob/dev/src/core/observer/array.js


//def メソッドは、Object.defineProperty カプセル化に基づくメソッドのレイヤーです。非常にシンプルです。探す手間を省くために、以下のコードを投稿します。
'../util/index' から { def } をインポートします 

//ネイティブ配列プロトタイプオブジェクトを保存します。const arrayProto = Array.prototype

// プロトタイプ接続を作成し、arrayMethods のプロトタイプを Array.prototype にポイントします
エクスポート const arrayMethods = Object.create(arrayProto)

const メソッドToPatch = [
  '押す'、
  'ポップ'、
  'シフト'、
  'シフト解除'、
  'スプライス'、
  '選別'、
  '逆行する'
]

methodsToPatch.forEach(関数 (メソッド) {
  // ネイティブメソッドをキャッシュ const original = arrayProto[method]
  def(arrayMethods, メソッド, 関数ミューテーター (...args) {
    var args = [], 
    len = 引数の長さ;
    while (len--) args[len] = arguments[len];
    const result = original.apply(this, args) // 元の配列メソッドの実行結果 const ob = this.__ob__ // この __ob__ は Observe のインスタンスです~~~~
    挿入させる
    スイッチ(メソッド){
      ケース 'プッシュ':
      ケース 'unshift':
        挿入された = 引数
        壊す
      ケース 'スプライス':
        挿入 = args.slice(2)
        壊す
    }
    if (inserted) ob.observeArray(inserted) // 配列が変更された場合は、再度observeArrayを呼び出します
    // 変更を通知する
    ob.dep.notify() //
    結果を返す
  })
})

これは Observer のコードです:

var Observer = 関数 Observer(値) {
    this.value = 値;
    this.dep = 新しい Dep();
    this.vmCount = 0;
    def(value, '__ob__', this); //ここで、Observeインスタンスが各オブジェクトデータにバインドされていることがわかります。したがって、上記のコードのthis.__ob__はこれです。if (Array.isArray(value)) { //ここで、データが配列型であるかどうかを判断します。そうであれば、observeArrayが使用されます。
      (hasProto) の場合 {
        protoAugment(値、配列メソッド);
      } それ以外 {
        copyAugment(値、配列メソッド、配列キー);
      }
      this.observeArray(value); //ここでは配列型のデータを次のように処理します} else {
      this.walk(値);
    }
  };

以下は observeArray の実装です。

Observer.prototype.observeArray = 関数 observeArray(items) {
    (var i = 0, l = items.length; i < l; i++) の場合 {
      observe(items[i]); // observeメソッドは以下のとおりです}
  };

ここでは、observe メソッドを見てみましょう。

関数 observe(値、asRootData) {
    if (!isObject(value) || value instanceof VNode) {
      戻る
    }
    var ob;
    if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
      ob = 値.__ob__;
    } それ以外の場合 (
      観察すべき &&
      !isServerRendering() &&
      (Array.isArray(値) || isPlainObject(値)) &&
      Object.isExtensible(値) &&
      !値._isVue
    ){
      ob = 新しいオブザーバー(値);
    }
    if (asRootData && ob) {
      ob.vmCount++;
    }
    戻り値
  }

これは def メソッドの実装に関するものです。非常に単純なので説明は省略します。

関数def (obj, キー, val, 列挙可能) {
    Object.defineProperty(obj, キー, {
      値: val、
      列挙可能: !!列挙可能、
      書き込み可能: true、
      設定可能: true
    });
}

上記は、Vue で配列の変更を監視する方法についての詳細です。Vue が配列を監視する方法の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • Vueで配列の変更を監視する方法
  • Vue 開発監視配列、オブジェクト、変数操作分析
  • Vue は配列の変更を監視し、ソースコード分析を行います。
  • Vue 携帯電話の物理監視キー + 終了プロンプト コード
  • Vue のディープ モニタリング (オブジェクトと配列の変更の監視) と監視例の即時実行
  • Vue親コンポーネントは子コンポーネントのライフサイクルを監視します
  • Vueはウィンドウを閉じるイベントをリッスンし、ウィンドウが閉じる前にリクエストを送信する機能を実装しています。
  • VueはTreeselect選択の変更操作を監視します
  • Vueはルートの変更を監視し、App.vueファイル内のページを更新します。

<<:  jsvc を使用して tomcat を起動する方法 (通常のユーザーとして実行)

>>:  (MariaDB) MySQL のデータ型とストレージメカニズムの包括的な説明

推薦する

オペレーターが知っておくべき 18 個の Nginx プロキシ キャッシュ構成のヒント (どれを知っていますか?)

アプリケーションや Web サイトのパフォーマンスが成功の重要な要素であることは誰もが知っています。...

SqlクエリMySqlデータベーステーブル名と説明テーブルフィールド(列)情報

以下では、SQL クエリ ステートメントを使用して、Mysql データベース内のテーブルのテーブル名...

Vue フロントエンド開発における keepAlive の使用方法の詳細な説明

目次序文keep-avlive フック関数keep-avliveはどのコンポーネントをキャッシュする...

MySQL アクティブ-アクティブ同期レプリケーションの 4 つのソリューションの詳細な説明

目次MySQLネイティブレプリケーションに基づくマスター-マスター同期ソリューションGaleraレプ...

Vue3はサイドナビゲーションテキストスケルトン効果コンポーネントをカプセル化します

Vue3プロジェクトのカプセル化サイドナビゲーションテキストスケルトン効果コンポーネント-グローバル...

MySQLがファントムリードを解決する方法の詳細な説明

1. ファントムリーディングとは何ですか?トランザクションにおいて、複数のクエリの後に結果セットの数...

WebページでjQueryを参照する方法

CDN(コンテンツ配信ネットワーク)を通じて参照できます。 jQuery は Google と Mi...

Vueコンポーネントの基本のまとめ

コンポーネントの基本1 コンポーネントの再利用コンポーネントは再利用可能な Vue インスタンスです...

docker エントリポイントファイルの詳細な説明

Dockerfile を作成するときは、コンテナが起動する前に初期化構成やカスタム構成を実行するため...

MySql8 WITH RECURSIVE 再帰クエリ親子コレクションメソッド

背景コメントに似た機能を開発する場合は、必要に応じてすべてのコメントのサブセットをクエリする必要があ...

XHTML 入門チュートリアル: XHTML とは何ですか?

HTMLとは何ですか?簡単に言えば、HTML は Web ページを作成するために使用されます。とて...

ES6 の Set および WeakSet コレクションの詳細な説明

目次セットは値が重複しない特別なコレクションです。セットコレクション基本API独自の価値判断セットを...

既存のMySQLデータベースの文字セットを統一する方法

序文データベースでは、一部のデータ テーブルとデータは latin1 であり、一部のデータ テーブル...

ES5とES6の違いを分析する

目次概要関数シグネチャオプションパラメータ非厳密モード例外処理実用要約する概要ご存知のとおり、ES6...

JavaScript を使用してカルーセル効果を実装する

この記事では、カルーセルマップの特殊効果を実現するためのJavaScriptの具体的なコードを参考ま...