vue2 watch实现原理

647 阅读2分钟

在Vue 2中,watch实现原理是基于JavaScript的Object.defineProperty方法和依赖追踪的概念。当你使用watch选项来监听一个数据属性时,Vue会在内部创建一个Watcher对象,然后通过Object.defineProperty将这个属性转化为访问器属性。

当该属性的值发生变化时,Vue会触发属性的setter方法。在setter方法中,Vue会通知相关的Watcher对象,表明这个属性已经被更新了。Watcher对象会调用回调函数,并执行相应的操作,比如更新视图或触发其他逻辑。

这里需要注意的是,Vue 2中的watch默认是浅层监听的,只能监听到对象或数组的引用变化,而无法深度监测对象内部属性的变化。如果需要深度监听对象内部属性的变化,可以通过设置deep选项为true来实现。

此外,Vue 2中的watch还支持其他选项,比如immediate用于指定是否在初始加载时立即执行回调函数,以及handler用于指定回调函数等。

总结起来,Vue 2中的watch实现原理是通过Object.defineProperty将要监听的属性转化为访问器属性,然后通过依赖追踪,当属性值发生变化时,通知相关的Watcher对象执行相应的回调函数。这样可以实现对数据的变化进行监测,并在变化发生时执行相应的逻辑操作。

以下是一个简化的内部实现示例,展示了Vue 2中watch选项的基本原理:

function Vue(options) {
  this.data = options.data;
  this.watchers = {};

  // 代理数据属性
  Object.keys(this.data).forEach(key => {
    this.proxyData(key);
  });

  // 创建watcher
  this.createWatchers(options.watch);
}

Vue.prototype.proxyData = function(key) {
  var self = this;
  Object.defineProperty(this, key, {
    get: function() {
      return self.data[key];
    },
    set: function(newValue) {
      self.data[key] = newValue;
      self.watchers[key].callback(newValue, self.watchers[key].value);
      self.watchers[key].value = newValue;
    }
  });
};

Vue.prototype.createWatchers = function(watch) {
  var self = this;
  Object.keys(watch).forEach(key => {
    self.watchers[key] = {
      callback: watch[key],
      value: self.data[key]
    };
  });
};

// 示例用法
var vm = new Vue({
  data: {
    message: 'Hello, Vue!'
  },
  watch: {
    message: function(newValue, oldValue) {
      console.log('新值: ' + newValue + ', 旧值: ' + oldValue);
    }
  }
});

vm.message = 'Hello, JavaScript!';
// 控制台输出: 新值: Hello, JavaScript!, 旧值: Hello, Vue!

在这个示例中,我们创建了一个Vue构造函数,其中定义了data对象和watchers对象。通过proxyData方法,我们将data对象中的每个属性都设置为Vue实例的访问器属性。在访问和修改这些属性时,我们实际上是在访问和修改data对象的对应属性。

createWatchers方法用于创建watchers对象,遍历watch选项中的每个属性,并将其存储在watchers对象中。每个属性都有一个callback回调函数和一个初始值value,用于在属性变化时执行回调。

在Vue实例中修改message属性时,触发了对应的访问器属性的setter方法。在setter方法中,我们调用了相应属性的回调函数,并传入新值和旧值。