码迷,mamicode.com
首页 > 其他好文 > 详细

Vue源码学习之数据初始化

时间:2019-04-15 00:59:51      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:blog   get   col   type   val   https   ons   turn   遍历   

首发地址:CJWbiu‘s Blog

  在这里思考一个问题,使用Vue的时候需要在创建Vue实例时传入一个option,这里包含了我们定义的props、methods、data等。而在methods的方法中获取data中的key值都是直接通过this.key获取option对象中的methods中的定义的方法如何通过this访问到data中的数据呢?

let vue = new Vue({
    el: ‘#app‘,
    methods: {
      say() {
        console.log(this.msg)
      }
    },
    data: {
      msg: ‘jjjjj‘
    }
})

  一开始我想是将datamethods中的数据全都挂载到了vm上,然而Vue实例上有methods中定义的方法,却没有data中的属性,data中的数据全部存储在vm._data中,通过this.key访问其实是this._data.key,Vue在这里做了一层代理,通过defineProperty设置了vm的getter和setter,而methods中的方法在initMethods方法中将其中的this绑定到了vm上,这样methods中方法访问的this也就指向了_data。 


  下面是参照源码相关逻辑的简化代码:

function MyVue(option) {
  this._init(option);
}

MyVue.prototype._init = function(option) {
  const vm = this; 
  vm.$options = option; //源码在此做了对子组件option的合并处理
  if(vm.$options.methods) initMethods(vm, vm.$options.methods); //源码中还有对props的处理,data、props、methods都会做查重处理,不能有相同的属性名
  if(vm.$options.data) initData(vm);
}

function initMethods(vm, methods) {
  const props = vm.$options.props
  for (const key in methods) {
    vm[key] = methods[key].bind(vm);  //将methods上的方法挂载到vm上并将方法中所有的this指向vm,通过下面的proxy就可以访问到_data上的属性
  }
}

function initData(vm) { //将data上数据复制到_data并遍历所有属性添加代理
  vm._data = vm.$options.data;
  const keys = Object.keys(vm._data); 
  let i = keys.length;
  while(i--) {  
    const key = keys[i];
    proxy(vm, `_data`, key);
  }
}
function proxy(target, sourceKey, key) {
  let sharedPropertyDefinition = {};
  sharedPropertyDefinition.get = function proxyGetter () {
    return this[sourceKey][key]
  }
  sharedPropertyDefinition.set = function proxySetter (val) {
    this[sourceKey][key] = val
  }
  Object.defineProperty(target, key, sharedPropertyDefinition)  //一层代理,每次访问this[key]时代理到this._data[key]
}

let app = new MyVue({
  methods: {
    say: function() {
      console.log(this.msg + this.age);
    }
  },
  data: {
    msg: ‘jjj‘,
    age: 33
  }
})
app.say(); //jjj33

 

Vue源码学习之数据初始化

标签:blog   get   col   type   val   https   ons   turn   遍历   

原文地址:https://www.cnblogs.com/cjw-ryh/p/10708098.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!