>  기사  >  웹 프론트엔드  >  Vue에서 감시자 데이터의 양방향 바인딩 원리를 이해하기 위한 기사(코드 포함)

Vue에서 감시자 데이터의 양방향 바인딩 원리를 이해하기 위한 기사(코드 포함)

奋力向前
奋力向前앞으로
2021-08-23 10:09:272251검색

이전 글 "Vue에서 관찰자 데이터의 양방향 바인딩 원리 분석(코드 공유) "에서는 Vue에서 관찰자 데이터의 양방향 바인딩 원리에 대해 배웠습니다. 다음 글은 Vue의 감시자 데이터의 양방향 바인딩 원리에 대한 이해를 제공합니다. 필요한 친구가 이를 참조할 수 있습니다.

Vue에서 감시자 데이터의 양방향 바인딩 원리를 이해하기 위한 기사(코드 포함)

vue 데이터 양방향 바인딩 원칙과 간단한 구현으로, 이 기사에서는 mvvmwatchervue数据双向绑定原理,和简单的实现,本文将实现mvvmwatcher

Vue에서 감시자 데이터의 양방향 바인딩 원리를 이해하기 위한 기사(코드 포함)

1)vue数据双向绑定原理-observer

2)vue数据双向绑定原理-wather

3)vue数据双向绑定原理-解析器Complie

vue数据双向绑定原理,和简单的实现,本文将实现mvvmWatcher

上面的步骤已经实现了监听器,和订阅器,当属性发生改变,发出通知,那么这个通知是通知谁呢,肯定是订阅者watcher.Watcher订阅者作为ObserverCompile之间通信的桥梁,主要做的事情是:

1、在自身实例化时往属性订阅器(dep)里面添加自己

2、自身必须有一个update()方法

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;
  },
};

订阅者要缓存自己,并且告诉监听器,要把我加到订阅器里面去。所以还要改造下监听器

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;
    },
    ....
  });

}

实例化Watcher的时候,调用get()方法,通过Dep.target=watcherInstance标记订阅者是当前watcher实例,强行触发属性定义的getter方法,getter方法执行的时候,就会在属性的订阅器dep添加当前watcher实例,从而在属性值有变化的时候watcherInstance就能收到更新通知。

实现MVVM

到这儿先将监听器Observer和监听者Watcher连起来,先模拟一些数据,实现简单的数据绑定

<div id="name"></div>
<script>
  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("#name");
  var vue = new Vue(
    {
      name: "hello world",
    },
    ele,
    "name"
  );
  setInterval(function () {
    vue.data.name = "chuchur " + new Date() * 1;
  }, 1000);
</script>

这可以看到div的和内容初始为hello world,每隔一秒之后变换为chuchur加时间戳,虽然是实现了,但是与想象的还差很多。是vue.name不是vue.data.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

1)

Vue 데이터 양방향 바인딩 원칙-observer

2) Vue 데이터 양방향 바인딩 원칙-wather 🎜🎜 🎜3) vue 데이터 양방향 바인딩 원칙 - 파서 Complie🎜🎜🎜vue데이터 양방향 바인딩 원칙 및 간단한 구현으로 이 기사에서는 <code>mvvmWatcher🎜🎜를 구현합니다. 위 단계에서는 이미 리스너와 구독자를 구현했습니다. 속성이 변경되고 알림을 발행하므로 이 알림을 누구에게 알려야 합니까? 감시자 구독자여야 합니다. 컴파일 간의 통신 브리지는 주로 다음을 수행합니다. 🎜🎜1. 자신을 인스턴스화할 때 구독자 속성(dep)에 자신을 추가해야 합니다. update() 메서드 🎜🎜3. 속성이 dep.notice() 알림을 변경하면 고유한 update() 메서드를 호출할 수 있습니다. , 컴파일에 바인딩된 콜백이 트리거되면 자체적으로 릴리스됩니다. 🎜rrreee🎜구독자는 자신을 캐시하고 청취자에게 나를 구독자에 추가하고 싶다고 알려야 합니다. 따라서 리스너를 수정해야 합니다🎜rrreee🎜Watcher를 인스턴스화할 때 get() 메서드를 호출하고 Dep.target=watcherInstance 태그를 전달하세요. 구독자는 속성에 의해 정의된 getter 메서드를 강제로 트리거하는 현재 watcher 인스턴스입니다. 속성의 구독자dep에서 현재 watcher 인스턴스를 추가하므로 속성 값이 변경될 때 watcherInstance가 업데이트 알림을 받을 수 있습니다. 🎜

MVVM

구현🎜여기서 먼저 Observer 리스너와 Watcher 리스너를 연결하고 먼저 일부 데이터를 시뮬레이션합니다. 간단한 데이터 바인딩을 달성하려면🎜rrreee🎜div의 내용이 처음에는 hello world이고 두 번째 코드마다 chuchur로 변경되는 것을 볼 수 있습니다. 타임스탬프 추가, 구현은 되었지만 아직 상상과는 거리가 멀다. vue.data.name이 아니라 vue.name이므로 Vue 인스턴스에 속성 프록시 메서드를 추가하여 에 액세스해야 합니다. code> vm의 속성 프록시는 vm.data의 속성에 접근하기 위한 것입니다. 수정된 코드는 다음과 같습니다. 🎜rrreee🎜그러면 vue를 통해 템플릿을 직접 수정할 수 있습니다. .name 데이터를 사용하는 경우 다음 단계는 파서 Complie를 구현하는 것입니다. 🎜🎜[End]🎜🎜권장 학습: 🎜vue.js tutorial🎜🎜

위 내용은 Vue에서 감시자 데이터의 양방향 바인딩 원리를 이해하기 위한 기사(코드 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 chuchur.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제