vue源码解析 —— 数据代理

1. 前言:因为vue源码是比较复杂的,考虑的东西比较多;而这里只是简单的了解下类似vue的mvvm框架的部分原理,所以我们用这个库: https://github.com/DMQ/mvvm  (仿vue实现的mvvm库,比vue简介,简单) ==>> 下面称其为 mvvm

2. 概念解析:

1) 数据代理: 通过一个对象代理对另一个对象(在前一个对象内部)中属性的操作(读/写)
2) vue 数据代理: 通过 vm 对象(即this)来代理 data 对象中所有属性的操作
3) 好处: 更方便的操作 data 中的数据
4) 基本实现流程
a. 通过 Object.defineProperty()给 vm 添加与 data 对象的属性对应的属性描述符
b. 所有添加的属性都包含 getter/setter
c. getter/setter 内部去操作 data 中对应的属性数据

3. 基本实现  (vue实现数据代理 / mvvm实现数据代理)

3.1 vue实现数据代理

vue源码解析 —— 数据代理_第1张图片

3.2 mvvm实现数据代理

vue源码解析 —— 数据代理_第2张图片

 

4. mvvm中数据代理的源码(主要由Object.definePropert这个方法实现 mvvm中的mvvm.js)

/*
相关于Vue的构造函数
 */
function MVVM(options) {
  // 将选项对象保存到vm
  this.$options = options;
  // 将data对象保存到vm和datq变量中
  var data = this._data = this.$options.data;
  //将vm保存在me变量中
  var me = this;
  // 遍历data中所有属性
  Object.keys(data).forEach(function (key) { // 属性名: name
    // 对指定属性实现代理
    me._proxy(key);
  });

  // 对data进行监视
  observe(data, this);

  // 创建一个用来编译模板的compile对象
  this.$compile = new Compile(options.el || document.body, this)
}

MVVM.prototype = {
  $watch: function (key, cb, options) {
    new Watcher(this, key, cb);
  },

  // 对指定属性实现代理   ===>>> 最重要的代码
  _proxy: function (key) {
    // 保存vm
    var me = this;
    // 给vm添加指定属性名的属性(使用属性描述)
    Object.defineProperty(me, key, {
      configurable: false, // 不能再重新定义
      enumerable: true, // 可以枚举
      // 当通过vm.name读取属性值时自动调用
      get: function proxyGetter() {
        // 读取data中对应属性值返回(实现代理读操作)
        return me._data[key];
      },
      // 当通过vm.name = 'xxx'时自动调用
      set: function proxySetter(newVal) {
        // 将最新的值保存到data中对应的属性上(实现代理写操作)
        me._data[key] = newVal;
      }
    });
  }
};

 

5. chrome浏览器的调试按钮

vue源码解析 —— 数据代理_第3张图片

 

文章仅为本人学习过程的一个记录,仅供参考,如有问题,欢迎指出!

你可能感兴趣的:(vue)