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

php中世界最好的语言
php中世界最好的语言オリジナル
2018-05-12 11:23:141660ブラウズ

今回は、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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。