Vue データ応答性原理の分析

php中世界最好的语言
リリース: 2018-05-12 11:23:14
オリジナル
1531 人が閲覧しました

今回は、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 の値を保存するためのクロージャが生成されます);

プロセスディスカッション

検証の結果、この関数は実際に使用できることがわかりました。次に、応答プロセスを議論しましょう:intputデータ(defineReActive())data change => 1. データの変更はどのように後続のイベントをトリガーしますか?よく考えてください。データを変更したい場合は、最初にデータを設定する必要があります。その後、メソッドを set() に追加するだけで問題ありません。

次に、別の重要な質問があります:

  1. Dependency Collection
  2. データ変更後にどのイベントがトリガーされるかをどのようにして知ることができるのでしょうか? Vue の場合:
  3. 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;
    ログイン後にコピー
  4. コード 1.2 は、当面は 2 つのメソッドの機能を理解するだけで済みます

--- その他の側面では、依存イベントを収集すると理解できます。は考慮されず、この関数は addSub ()

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.target とは何ですか?依存関係を収集するために Dep.target が必要なのはなぜですか?

Dep はクラスであり、Dep.target はクラスの属性であり、dep インスタンスの属性ではありません。
  1. Dep クラスはグローバルに利用できるため、Dep.target にグローバルにアクセスでき、その値を任意に変更できます。
  2. get メソッドは非常に一般的ですが、データ値を取得するために使用するたびに dep.depend() を呼び出すことは不可能です。

dep.depend() は実際には dep.addSub(Dep.target) です。

その場合、使用前に Dep.target をオブジェクトに設定し、サブスクリプションの完了後に Dep.target = null を設定するのが最善の方法です。
  1. 検証

  2. コードの波が利用可能かどうかを検証する時が来ました

    //代码 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中文网其它相关文章!

    推荐阅读:

    React Form组件封装步骤详解

    JS跨域POST实现步骤详解

以上がVue データ応答性原理の分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!