この記事の例では、双方向データバインディングを実装するためのVueの具体的なコードを参考までに共有しています。具体的な内容は次のとおりです。 Vueの配列とオブジェクトは異なるバインディングメソッドを使用します 1. Vueオブジェクトデータバインディング(1)データ検出 jsでは、Object.defineProperty()とES6プロキシを使用してオブジェクトを検出します。 vue2.x では、Object.defineProperty() を使用してオブジェクト上のデータを検出します。まず、次のコードを使用して Object.defineProperty をカプセル化します。 関数defineReactive(データ、キー、値){ if(typeof val === 'object') 新しいオブザーバー(val) dep = new Dep(); Object.defineProperty(データ、キー、値) { 列挙可能: true、 設定可能: true、 取得: 関数 () { 依存関係 戻り値: }, 設定: 関数() { if(val === newVal) { 戻る ; } val = 新しいVal; dep.notify() } } } 渡す必要があるパラメータは、データ、キー、および val のみです。データ内のキーからデータが読み取られるたびに Get がトリガーされ、データが変更されるたびに set がトリガーされます。 (2)依存関係の収集 最初に依存関係を収集し、プロパティが変更されたときに、収集した依存関係をループで再度トリガーします。ゲッターで依存関係を収集し、セッターで依存関係をトリガーします。 依存クラス Dep デフォルトクラス Dep をエクスポートします { コンストラクタ() { this.subs = [] } サブルーチンを追加します。 this.subs.push(サブ) } サブルーチンを削除します 削除(this.subs, sub) } 依存する() { if(ウィンドウ.ターゲット) { this.addSub(ウィンドウ.ターゲット) } } 通知() { const subs = this.subs.slice() for(let i = 0, l = subs.length; i < l; i++) { subs[i].update() } } } 関数remove(arr, item) { (arr.length)の場合{ 定数インデックス = arr.indexOf(item) if(インデックス > -1) { arr.splice(インデックス, 1) を返す } } } ウォッチャークラスは、私たちが収集した依存関係です デフォルトクラスWatcherをエクスポートします{ コンストラクタ(vm, expOrFn, cb) { this.vm = vm this.getter = parsePath(expOrFn) this.cb = cb this.value = this.get() } 得る() { window.target = これ 値を this.getter.call(this.vm, this.vm) にします。 window.target = 未定義 戻り値 } アップデート() { const oldValue = this.value this.value = this.get() this.cb.call(this.vm、this.value、oldValue) の呼び出し } } (3)全てのキーを再帰的に検出する(オブザーバー) エクスポートクラスObserver { コンストラクタ(値) { this.value = 値; if(!Array.isArray(値)) { this.walk(値) } } 歩く(オブジェクト) { 定数キー = Object.keys(obj) for(let i = 0; i < keys.length; i++) { 定義Reactive(obj, キー[i], obj[キー[i]]) } } } Observerクラスはオブジェクトのすべてのプロパティをレスポンシブにします 2.配列変更検出(1)配列の変更を追跡するには、インターセプターを使用してプロトタイプメソッドをオーバーライドします。 const arrayProto = Array.prototype エクスポート const arrayMethods = Object.create(arrayProto); // 配列プロトタイプと同じオブジェクトをインターセプターとして ['push','pop','shift','unshift','splice','sort','reverse'].forEach(function (method) { const オリジナル = arrayProto[メソッド] Object.defineProperty(配列Methods, メソッド, { 値: 関数ミューテーター(...args) { 元の値を返す。(this, args) }, 列挙可能: false、 書き込み可能: true、 設定可能: true }) }) インターセプターオーバーライドプロトタイプには1つの文しかありません value.__proto__ = 配列メソッド __proto__プロパティがない場合、VueはこれらのarrayMethodsを検出された配列にマウントします。 配列は、ゲッターで依存関係を収集するのに対し、配列によってトリガーされる依存関係はインターセプターにあるという点でオブジェクトに似ています。 配列の依存関係は Observer インスタンスに保存され、ゲッターとインターセプターの両方からアクセスできる必要があります。 __ob__ は列挙不可能な属性であり、この属性の値は現在の Observer インスタンスです。 Dep インスタンスを Observer 属性に保存します。値にすでに __ob__ 属性がある場合は、値の変更が繰り返し検出されるのを避けるために、Observer インスタンスを再度作成する必要はありません。 配列の依存関係などの通知を送信する this.__ob__.dep.notify(); (2)データの変化を検知するための具体的な方法 配列内の各項目をループし、observe関数を実行して変更を検出します。 配列を観察(アイテム) { for(let i = 0; l = items.length; i < l; i++) { アイテム[i]を観察します。 } } 配列は新しい要素を検出する必要がある push、unshift、spliceなどのメソッドをインターセプトし、挿入された引数を格納することで if(挿入) ob.observeArray(挿入) 要約:配列は Object とは異なる方法で変更を追跡するため、変更を追跡するために配列のプロトタイプを上書きするインターセプターを作成します。グローバル Array.prototype を汚染しないように、Observer では __proto__ のみを使用して、変更を検出する必要がある配列のプロトタイプを上書きします。 Array は Object と同じ方法で依存関係を収集します。Object はゲッターで収集され、インターセプターでトリガーされ、依存関係は Observer インスタンスに保存されます。 Observer では、検出された各データを __ob__ でマークし、this(Observer) を __ob__ に保存します。これは主に、同じデータが 1 回だけ検出されることを保証するためです。さらに、__ob__ を通じて Observer インスタンスに保存された依存関係を簡単に取得できます。配列の各項目を応答可能にするには、配列をループする必要があります。配列に新しい要素が追加されると、パラメータを抽出し、observeArray を使用して新しいデータの変更を検出します。配列の場合、プロトタイプ メソッドのみをインターセプトでき、一部の固有のメソッドはインターセプトできません。 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: JDBC および MySQL 一時テーブルスペースの詳細な分析
>>: Linux でファイルをあいまい検索するのに適したコマンドは何ですか?
目次Linux 環境変数とプロセスアドレス空間コードを通じて環境変数を取得するプロセスアドレス空間な...
目次最近Reactを勉強していて、今は仕事でVueを使っています。学習の過程で、両者を比較して理解を...
この記事は、@C7210 によって翻訳されたブログ「Usability Counts」からの翻訳です...
css-vars-ポニーフィルCSS 変数を使用して Web ページのスキニングを実現すると、互換...
最近、リンク データについていくつか調査していて、rdf データベースを使用する必要があったため、v...
最近、MySQL の起動中にエラーが発生しました。エラー メッセージは次のとおりです。 エラー 20...
Harbor は、Docker イメージを保存および配布するためのエンタープライズ レベルのレジスト...
1. MySQL アーキテクチャストレージ エンジンを紹介する前に、まずは MySQL アーキテクチ...
目次予備作業バックエンド構築フロントエンドページダイレクトレンダリングsetTimeout ページン...
セルのパディングは、セルの内容と境界線の間の距離です。基本的な構文<TABLE セルパディング...
序文トランザクション データ ディクショナリとアトミック DDL は、MySQL 8.0 で導入され...
doctype もその 1 つです。 <!DOCTYPE HTML PUBLIC "...
最初のステップは、対応するデータベースモジュール(sql)をプロジェクトファイル( .pro )に追...
目次1. NFS の概要2. NFS構築1. NFSサーバーの構築2. NFSクライアントの構築3....
目次負荷分散負荷分散分類1. DNS 負荷分散2. IP負荷分散3. リンク層の負荷分散4. ハイブ...