Vue源码分析-数据代理

数据代理

实现data的数据代理

  // 保存optionsvm

  this.$options = options || {};

  // 保存data数据到vm _data

  var data = this._data = this.$options.data;

  // 保存vm

  var me = this;

  // 数据代理

  // 代理data属性数据到vm

  // 遍历data数据中所有属性名成一个数组

  Object.keys(data).forEach(function (key) {

    // 进行数据代理

    me._proxyData(key);  关于me:每个函数都有this,通过me保存this(vm实例对象)

  });

 

 

  // 代理data属性到vm

  _proxyData: function (key, setter, getter) {

    var me = this;  //this指向vm实例对象

    setter =

      setter ||

      Object.defineProperty(me, key, {

        configurable: false, // 不能重新配置

        enumerable: true, // 可以被遍历

        get: function proxyGetter() {

          // 代理属性读操作

          return me._data[key]; // 返回原属性的值

        },

        set: function proxySetter(newVal) {

          // 代理属性写操作

          me._data[key] = newVal; // 设置原属性的值

        },

      });

  },

代理computed计算属性到vm

  this._initComputed();

 

  _initComputed: function () {

    var me = this; //vm实例对象

    // 获取computed对象

    var computed = this.$options.computed;

    if (typeof computed === "object") {

      Object.keys(computed).forEach(function (key) {

        // 数据代理

        Object.defineProperty(me, key, {

          get:

            typeof computed[key] === "function"

              ? computed[key]

              : computed[key].get,

          // 计算属性不需要设置,计算属性当里面的值发生变化会自动更新

          set: function () {},

        });

      });

    }

  },

 

       在创建mvvm实例对象的时候会传入一个option配置对象,在mvvm构造函数中把当前的配置对象保存到$options,把配置对象中的data保存在实例对象_data和变量data中,通过Object.keys()方法获取到data对象中的所有属性,并且遍历调用_proxyData方法实现数据代理,该方法内部通过Object.defineProperty方法将data中每个属性的值逐一添加到vm实例身上,并且重写了get和set方法,在外部通过vm.msg获取该属性值的时候,会将vm._data对应的msg进行返回,外部设置vm.msg值的时候,进入set方法,修改vm._data对应msg的值

       代理配置对象中data的值后,会通过调用_initComputed方法将配置对象的computed属性代理到data中,也是通过Object.definePrototype方法,若代理属性的值是一个函数,将次函数作为get方法,若对应的是一个对象,对象身上的get对应的值作为此代理属性的get方法

 

猜你喜欢

转载自blog.csdn.net/shkstart/article/details/108456623