前書き: 最近、チームで共有を行う必要がありましたが、共有方法がわかりませんでした。最後に、vue のソースコードを勉強したいとずっと思っていたので、今日「この機会に」勉強してみました。
Vue のデータ バインディングに関する記事はインターネット上にすでにたくさんありますが、自分で書くのと、デモを入力するのと、他の人の記事を読むのではまったく違います。だから...ポーターがやって来ます
現在、主に 3 つのタイプがありますデータ バインディングの実装方法:
1. ダーティ値チェック (angular.js) データ変更を検出するためのポーリング
DOM イベント (ユーザーのテキスト入力、ボタンのクリックなど)。 (ngクリック)
XHR応答イベント($http)
ブラウザ位置変更イベント($location)
タイマーイベント($timeout, $interval)
$digest()または$apply()を実行
2 . Object.defineProperty は、データを監視するオブジェクトの取得とセットをハイジャックします。 (vue)
3. パブリッシャー/サブスクライバーモードでデータとビューの自動同期を実現
Object.definePropertyの利点
「ダーティ値検出」 - データ変更後、すべてのデータとビュー間のバインディング関係をテストするデータが変更されたかどうかを識別します。変更を処理すると、さらに他のデータも変更される可能性があるため、データ変更が発生しなくなるまでこのプロセスが数回繰り返され、変更されたデータが View に送信され、ページ表示が更新されます
Object.defineProperty () はデータに対する操作を監視し、データ同期を自動的にトリガーできます。さらに、同期は異なるデータに対してトリガーされるため、すべてのデータに対してテストを実行するのではなく、変更をバインドされたビューに正確に送信できます。
Object.definePropertyの使い方
var a = {}; Object.defineProperty(a, "b", { set: function (newValue) { console.log("我被赋值了!" + newValue); }, get: function () { console.log("我被取值了!"); return 2 } }) a.b = 3; //我被赋值了! console.log(a.b); //我被取值了! //打印 2
上記の例からわかるように、Object.definePropertyは3つのパラメータを渡します
最初のパラメータ:オブジェクト
2番目のパラメータ:aオブジェクトのbプロパティ
3 つ目: 有用な値、設定、取得、構成可能な属性を含む多くの属性があります
データ バインディングの原則:
1. データ オブジェクトのすべての属性を監視するデータ リスナー オブザーバーを実装します。最新値を取得し、dep 配列に通知
2. 命令パーサーを実装する各要素ノードの命令をコンパイル、スキャン、解析し、命令テンプレートに従ってデータを置き換えます
3. サブスクライブして受信できる dep 配列を実装します。各属性の変更通知、コマンドでバインドされた対応するコールバック関数の実行、ビューの更新
1. オブザーバーの実装
var data = {name: 'beidan'}; observe(data); data.name = 'test'; // 监听到值变化了 beidan 变成 test function observe(data) { if (!data || typeof data !== 'object') { return; } // 取出所有属性遍历 Object.keys(data).forEach(function(key) { defineReactive(data, key, data[key]); }); }
3. コンパイル
function defineReactive(data, key, val) { Object.defineProperty(data, key, { enumerable: true, // 可枚举 configurable: false, // 不能再define get: function() { return val; }, set: function(newVal) { console.log('监听到值变化了 ', val, ' 变成 ', newVal); val = newVal; } }); }
です。すべてはこの記事の内容のために この記事の内容が皆さんの勉強や仕事に少しでもお役に立てれば幸いです。また、PHP 中国語 Web サイトも応援したいと思っています。