1. はじめに
エッセイ「Vue データ ドライバーのシミュレーション 1」の最後で、監視対象のプロパティがオブジェクトの場合はどうなるかについて説明しました。そうすると、このオブジェクトの他のプロパティを監視することはできないでしょうか?
次のように:
ユーザーの名前と年齢属性が変更された場合、それらが変更されたことをどうやって知ることができますか?
今日はこの問題を解決しましょう。
Vue のソース コードを読むと、Observer コンストラクターを使用してオブジェクトごとに Observer オブジェクトを作成し、データを監視していることがわかりました。データ内の属性がオブジェクトの場合、それは Observer を通じて監視されます。
実際、中心となるアイデアはツリーの事前順序走査です (ツリーについては、こちらを参照してください)。上記のデモのデータをグラフにすると、次のように明確になります:
さて、一般的なアイデアを明確にしたので、一緒にオブザーバーを作成しましょう。
2. オブザーバーの構造
オブザーバーの全体的な構造は次のとおりです:
function Observer(data){ //如若this不是Observer对象,即创建一个 if(!(this instanceof Observer)){ return new Observer(data); } this.data = data; this.walk(data); } let p = Observer.prototype = Object.create(null); p.walk = function(data){ /* TODO:监听data数据中的所有属性, 并查看data中属性值是否为对象, 若为对象,就创建一个Observer实例 */ } p.convert = function(key, val){ //TODO:通过Object.defineProperty监听数据 }
それでは、walk メソッドと Convert メソッドを一緒に完成させましょう。
-walk-
まず、次のように、walk メソッドでデータ オブジェクトのすべての属性の監視を実装します。
p.walk = function(data){ let keys = Object.keys(data); keys.forEach( key => { let val = data[key]; this.convert(key, val); }); }
そして、属性はオブジェクトである可能性があるため、それらを監視する必要があります。
どうすればいいですか?
オブジェクトの場合は、Observer コンストラクターを再度使用して処理します。
は次のとおりです:
p.walk = function(data){ let keys = Object.keys(data); keys.forEach( key => { let val = data[key]; //如果val为对象,则交给Observer处理 if(typeof val === 'object'){ Observer(val); } this.convert(key, val); }); }
Observer を直接使用してオブジェクトを処理すると、親オブジェクトとの接続が失われるのではないかという疑問があるかもしれません。
しかし、そうではありません。JavaScript はオブジェクトのアドレス関係を指しているのに、その関連付けが失われる可能性があります。
-convert-
Convert メソッドの場合は、いつものように、次のように Object.defineProperty を使用してデータを監視します。
p.convert = function(key, val){ Object.defineProperty(this.data, key, { get: ()=>{ console.log('访问了'+key+' 值为'+val); return val; }, set: (newVal)=>{ console.log('设置了'+key+' 值为'+newVal); if(newVal !== val){ val = newVal; } } }); }
さて、簡単な Observer を構築しましょう。次へ 各属性が正常に監視されるかどうかをテストします。
<script src="./observer.js"></script> <script> let data = { user: { name: 'Monkey', age: 24 }, lover: { name: 'Dorie', age: 23 } }; Observer(data); </script>
効果は次のとおりです:
以上がこの記事の全内容です。皆様の学習に役立つことを願っております。また、皆様にも PHP 中国語 Web サイトをサポートしていただければ幸いです。
Vue データ駆動型シミュレーションの実装 2 関連記事の詳細については、PHP 中国語 Web サイトに注目してください。