ホームページ > 記事 > ウェブフロントエンド > Vue データの応答性を実装する方法
今回は、Vue のデータ応答性を実装する方法と、Vue のデータ応答性を実装するための 注意点 について説明します。以下は実際的なケースです。見てみましょう。
前書き
Vue のデータ応答は主に Object.defineProperty() に依存していますが、全体のプロセスはどのようなものですか?私たち独自のアイデアで Vue の道を歩むということは、実際には、Vue の原則をエンドポイントとして採用することを意味します。実装プロセスを逆にしましょう。 この記事のコードはすべてロープロファイル バージョンであり、多くの箇所は厳密ではありません。たとえば、if(typeof obj === 'object') は、obj がオブジェクトである可能性もありますが、obj がオブジェクトであるかどうかを判断します。array などのデータですが、この記事では簡単のため、array の場合は 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; } }); }たとえば、 const obj = {} として、defineReactive(obj,'a',2) メソッドを呼び出します。このとき、関数内では、val=2 となり、毎回 obj.a の値が返されます。 obj.aの設定時にvalの値も設定されます。 (defineReactive が呼び出されるたびに、val の値を保存するためのクロージャが生成されます);
プロセスディスカッション
検証の結果、この関数は実際に使用できることがわかりました。次に、応答プロセスについて説明します。Dependency Collection
データ変更後にどのイベントがトリガーされるかをどのようにして知ることができるのでしょうか? Vue の場合: Use data => View; データはビューのレンダリングに使用されるため、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;コード 1.2 は、当面は 2 つのメソッドの機能を理解するだけで済みます
//代码 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.target とは何ですか?依存関係を収集するために Dep.target が必要なのはなぜですか?
検証
コードの波が利用可能かどうかを検証する時が来ました//代码 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;
此时浏览器上的界面是这样的
然后在下打开了控制台开始调试,输入:
obj.html = 'I am fine thank you'
然后就发现,按下回车的那一瞬间,奇迹发生了,页面变成了
结尾
Vue数据响应的设计模式和订阅发布模式有一点像,但是不同,每一个dep实例就是一个订阅中心,每一次发布都会把所有的订阅全部发布出去。
Vue的响应式原理其实还有很大一部分,本文主要讨论了Vue是如何让数据进行响应,但是实际上,一般的数据都是很多的,一个数据被多处使用,改变数据之后观察新值,如何观察、如何订阅、如何调度,都还有很大一部分没有讨论。主要的三个类Dep(收集依赖)、Observer(观察数据)、Watcher(订阅者,若数据有变化通知订阅者),都只提了一点点。
之前写有一篇Vue响应式----数组变异方法,针对Vue中对数组的改造进行讨论。当然之后有更多其他的文章,整个数据响应流程还有很多内容,三个主要的类都还没有讨论完。
其实阅读源码不仅仅是为了知道源码是如何工作的,更重要的是学习作者的思路与方法,我写的文章都不长,希望自己能够每次专注一个点,能够真真实实领悟到这一个点的原理。当然也想控制阅读时间,免得大家看到一半就关闭了。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上がVue データの応答性を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。