この記事では主に Vue のデータ応答性の原理を紹介します。必要な方は参考にしてください。
Vue のデータ応答は主にオブジェクトに依存します。 .defineProperty() では、全体のプロセスはどのようなものでしょうか?私たち独自のアイデアで Vue の道を歩むということは、実際には、Vue の原則をエンドポイントとして採用することを意味します。実装プロセスを逆にしましょう。 この記事のコードは低構成バージョンであり、多くの部分は厳密ではありません。たとえば、if(typeof obj === 'object') は、obj がオブジェクトである可能性もありますが、obj がオブジェクトであるかどうかを判断します。配列などのデータを使用することもできますが、簡単のため、この記事では判定オブジェクトを表すために直接記述し、配列には Array.isArray() を使用します。
データの変換まずオブジェクトを変換する関数を書いてみましょう: なぜ最初にこの関数を書く必要があるのでしょうか? データの変換は最も基本的で重要な手順であるため、後続のすべての手順はこの手順に依存します。
// 代码 1.1 function defineReactive (obj,key,val) { Object.defineProperty(obj,key,{ enumerable: true, configurable: true, get: function () { return val; }, set: function (newVal) { //判断新值与旧值是否相等 //判断的后半段是为了验证新值与旧值都为NaN的情况 NaN不等于自身 if(newVal === val || (newVal !== newVal && value !== value)){ return ; } val = newVal; } }); }
次に、別の重要な質問があります:
Dependency Collection
データ変更後にどのイベントがトリガーされるかをどうやって知ることができるのでしょうか? Vue の場合:
データを使用 => ビュー; データはビューのレンダリングに使用されるため、Vue はデータ属性を変換して依存関係を収集するときに依存関係を収集するのに最適なタイミングです。
// 代码 1.2 class Dep { constructor(){ //订阅的信息 this.subs = []; } addSub(sub){ this.subs.push(sub); } removeSub (sub) { remove(this.subs, sub); } //此方法的作用等同于 this.subs.push(Watcher); depend(){ if (Dep.target) { Dep.target.addDep(this); } } //这个方法就是发布通知了 告诉你 有改变啦 notify(){ const subs = this.subs.slice() for (let i = 0, l = subs.length; i < l; i++) { subs[i].update(); } } } Dep.target = null;
notify() と同等です --- このメソッドはより直観的であり、依存するすべての update() メソッドを実行します。後でビューを変更するだけです。
この記事では主にデータ応答のプロセスについて説明し、Watcher クラスについては詳しく説明しません。そのため、Dep.1 のメソッドの機能を知っていれば十分です。次に、コード 1.1 を変更します
//代码 1.3 function defineReactive (obj,key,val) { const dep = new Dep(); Object.defineProperty(obj,key,{ enumerable: true, configurable: true, get: function () { if(Dep.target){ //收集依赖 等同于 dep.addSub(Dep.target) dep.depend() } return val; }, set: function (newVal) { if(newVal === val || (newVal !== newVal && val !== val)){ return ; } val = newVal; //发布改变 dep.notify(); } }); }
Dep はクラスであり、Dep.target はクラスの属性であり、dep インスタンスの属性ではありません。
Dep クラスはグローバルに利用できるため、Dep.target にグローバルにアクセスでき、その値を任意に変更できます。
get メソッドは非常に一般的ですが、データ値を取得するために使用するたびに dep.depend() を呼び出すことは不可能です。
dep.depend() は実際には dep.addSub(Dep.target) です。
その場合、使用前に Dep.target をオブジェクトに設定し、サブスクリプションの完了後に Dep.target = null を設定するのが最善の方法です。 verificationsコードの波の可用性を検証する時期デバッグを開始して、次のように入力します:
//代码 1.4 const obj = {};//这一句是不是感觉很熟悉 就相当于初始化vue的data ---- data:{obj:{}}; //低配的不能再低配的watcher对象(源码中是一个类,我这用一个对象代替了) const watcher = { addDep:function (dep) { dep.addSub(this); }, update:function(){ html(); } } //假装这个是渲染页面的 function html () { document.querySelector('body').innerHTML = obj.html; } defineReactive(obj,'html','how are you');//定义响应式的数据 Dep.target = watcher; html();//第一次渲染界面 Dep.target = null;
そして、Enterを押した瞬間に奇跡が起こり、ページが
Vue の応答性の原則は、実際には Vue がどのようにデータを応答させるかについて主に説明しますが、実際には、データを変更した後、さまざまな場所で 1 つのデータが使用されます。 、観察方法、購読方法、スケジュール方法など、まだ議論されていないことがたくさんあります。 3 つの主要なクラス、Dep (依存関係を収集)、Observer (データを監視)、Watcher (サブスクライバー、データが変更された場合にサブスクライバーに通知) については、少しだけ説明しました。
私は以前、Vue での配列の変換について説明する「Vue の応答性 - 配列の変更方法」という記事を書きました。もちろん、今後さらに他の記事が登場する予定ですが、データ応答プロセス全体にはまだ多くの内容があり、3 つの主要なクラスについてはまだ説明されていません。
実際、ソースコードを読むことは、ソースコードがどのように動作するかを知ることだけでなく、それよりも重要なのは、著者のアイデアや手法を学ぶことです。私が書く記事は、1つの点に集中できることを願っています。ここまでの原理を一度に理解してください。もちろん、途中で読んで閉じてしまわないように、読む時間をコントロールしたいと思っています。
関連する推奨事項:
以上がVue データの応答性の原則に関する簡単な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。