ホームページ >ウェブフロントエンド >Vue.js >Vue のウォッチャー データの双方向バインディング原理を理解するための記事 (コード付き)

Vue のウォッチャー データの双方向バインディング原理を理解するための記事 (コード付き)

奋力向前
奋力向前転載
2021-08-23 10:09:272322ブラウズ

前回の記事「vueにおけるオブザーバーデータの双方向バインディング原理の分析(コード共有)」では、vueにおけるオブザーバーデータの双方向バインディング原理について学びました。 。次の記事では、Vue のウォッチャー データの双方向バインディングの原理を理解することができます。これには一定の参照価値があり、困っている友人はそれを参照できます。

Vue のウォッチャー データの双方向バインディング原理を理解するための記事 (コード付き)

vue データ双方向バインディングの原則と簡単な実装。この記事では、mvvm ウォッチャーの を実装します。

Vue のウォッチャー データの双方向バインディング原理を理解するための記事 (コード付き)

1)

vue データの双方向バインディング原則 - オブザーバー

2)

vue データ 2- way バインディング 定義済みの原則-wather

3)

vue データ双方向バインディング原則-パーサー Complie

vuedata two-wayバインディング原則、および簡単な実装、この記事では mvvmWatcher

を実装します。上記の手順では、リスナーとサブスクライバーがすでに実装されています。プロパティが変更されると、通知が行われます。では、この通知は誰に通知されるのでしょうか? それはサブスクライバ

watcher.Watcher である必要があります。サブスクライバは、Observer の間の通信ブリッジとして機能します。 Compile の主な処理は次のとおりです:

1. 自身をインスタンス化するときに、自身をプロパティ サブスクライバー (

dep) に追加します

2. それは、

update()Method

3. 属性が

dep.notice() に変更されると、独自の update() メソッドを呼び出して、 Compile でバインドされたコールバックはそれ自体を解放します。

// Watcher
function Watcher(vm, exp, cb) {
  this.cb = cb;
  this.$vm = vm;
  this.exp = exp;
  // 此处为了触发属性的getter,从而在dep添加自己,结合Observer更易理解
  this.value = this.get(); // 将自己添加到订阅器的操作
}
Watcher.prototype = {
  update: function () {
    this.run(); // 属性值变化收到通知
  },
  run: function () {
    var value = this.get(); // 取到最新值
    var oldVal = this.value;
    if (value !== oldVal) {
      this.value = value;
      this.cb.call(this.$vm, value, oldVal); // 执行Compile中绑定的回调,更新视图
    }
  },
  get: function () {
    Dep.target = this; // 将当前订阅者指向自己, 缓存
    var value = this.$vm[this.exp]; // 强制触发监听的getter,添加自己到属性订阅器中
    Dep.target = null; // 添加完毕,重置释放
    return value;
  },
};

サブスクライバーは自分自身をキャッシュし、私をサブスクライバーに追加したいことをリスナーに伝える必要があります。したがって、

Watcher

をインスタンス化するときにリスナー

function defineReactive(data, key, val) {
  var dep = new Dep()
  observe(val); // 监听子属性
  Object.defineProperty(data, key, {
    ....
    get: function() {
      // 由于需要在闭包内添加watcher,所以可以在Dep定义一个全局target属性,暂存watcher, 添加完移除
      Dep.target && dep.addDep(Dep.target);
      return val;
    },
    ....
  });

}
を変更し、get() メソッドを呼び出して、Dep.target=watcherInstance## を渡す必要があります。 # サブスクライバを現在の watcher インスタンスとしてマークし、プロパティによって定義された getter メソッドを強制的にトリガーします。getter メソッドが実行されると、プロパティのサブスクライバー dep現在の watcher インスタンスを追加して、プロパティ値が変更されたときに watcherInstance が更新通知を受信できるようにします。 実装

MVVM

ここでは、まずリスナー

Observer

とリスナー Watcher を接続し、最初にいくつかのデータをシミュレートします。単純なデータ バインディングを実装します<pre class="brush:php;toolbar:false">&lt;div id=&quot;name&quot;&gt;&lt;/div&gt; &lt;script&gt; function Vue(data, el, exp) { this.data = data; observe(data); el.innerHTML = this.data[exp]; // 初始化模板数据的值 new Watcher(this, exp, function (value) { el.innerHTML = value; }); return this; } var ele = document.querySelector(&quot;#name&quot;); var vue = new Vue( { name: &quot;hello world&quot;, }, ele, &quot;name&quot; ); setInterval(function () { vue.data.name = &quot;chuchur &quot; + new Date() * 1; }, 1000); &lt;/script&gt;</pre>

div

の合計は最初は hello world で、2 秒ごとに chuchur に変化することがわかります。タイムスタンプは実装されていますが、まだ想像とは程遠いものです。これは vue.data.name ではなく vue.name なので、ここでは vue インスタンスにプロパティ プロキシ メソッドを追加して vm にアクセスする必要があります。 の属性プロキシは、vm.data の属性にアクセスするためのものです。変更されたコードは次のとおりです:

function Vue(options) {

  this.$options = options || {};
  this.data = this.$options.data;
  // 属性代理,实现 vm.xxx -> vm.data.xxx
  var self = this;
  Object.keys(this.data).forEach(function(key) {

    self.proxy(key); // 绑定代理属性

  });
  observe(this.data, this);
  el.innerHTML = this.data[exp]; // 初始化模板数据的值
  new Watcher(this, exp, function(value) {

    el.innerHTML = value;

  });
  return this;

}

Vue.prototype = {

  proxy: function(key) {
    var self = this;
    Object.defineProperty(this, key, {
      enumerable: false,
      configurable: true,
      get: function proxyGetter() {
        return self.data[key];
      },
      set: function proxySetter(newVal) {
        self.data[key] = newVal;
      }
    });
  }

}
これで、vue を通じてテンプレート データを直接変更できます。 .name

、次のステップはパーサーを実装することです

Complie [終了]

推奨される学習:

vue.js チュートリアル

以上がVue のウォッチャー データの双方向バインディング原理を理解するための記事 (コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はchuchur.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。