Vue源码分析

Vue.js的核心思想就是数据驱动,就是数据驱动视图,对视图的修改不会改变DOM,而是通过修改数据,这样代码维护比较方便

Vue中源码:

目录

1. 新建一个new发生了什么

 2. 当我们新建一个data(){return {}}的时候,为什么可以在其他的比如mounted()中调用


1. 新建一个new发生了什么

 2. 当我们新建一个data(){return {}}的时候,为什么可以在其他的比如mounted()中调用

总结:比如我们调用data中定义的message的时候也就是this.message的时候,在入口函数中调用了Vue的原生函数,并且调用了state这个模块,这个模块也是自己写的,state中先执行initState()函数,判断如果是data的话就进一步执行initDate函数,将vm也就是this当作参数传入,这个函数中会首先判断data是否是一个函数,如果是一个函数就直接getDate(data,vm),getDate()这个函数是一个try catch,成功的时候是将data的this指向改成是当前上下文也就是vm,然后进行返回,data=_data,所以我们使用this.data=this._data,但是一般来说_代表的是私有属性或者方法不建议直接访问,因为判断的是一个data是否是一个函数,所以推荐data(){return{}}这种写法来定义data

这个时候其实是发生了一些事情,首先是在进口函数中调用了/core/state.js进行状态初始化

 vm:component=this绑定的就是this,验证options,当options不同的时候执行不同的代码,所以在新建一个data的时候,其实就是执行了if(opts.data)判断并去执行initData()函数

function initData (vm: Component) {
  let data = vm.$options.data//data获取到定义的data
//判断data是不是一个函数,如果是函数就直接执行getData(data,vm),所以建议data写出函数的形式
//getData()函数就是返回data,并且通过call函数改变data的this指向,
//而且data=vm._data将data的值赋给vm._data,vm也就是this,
//所以是可以通过this._data调用data的数据
  data = vm._data = typeof data === 'function'
    ? getData(data, vm)
    : data || {}
  if (!isPlainObject(data)) {
    data = {}
    process.env.NODE_ENV !== 'production' && warn(
      'data functions should return an object:\n' +
      'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
      vm
    )
  }
  // proxy data on instance
//获取keys和props methods等
  const keys = Object.keys(data)
  const props = vm.$options.props
  const methods = vm.$options.methods
  let i = keys.length
  while (i--) {
    const key = keys[i]
    if (process.env.NODE_ENV !== 'production') {
      if (methods && hasOwn(methods, key)) {
        warn(
          `Method "${key}" has already been defined as a data property.`,
          vm
        )
      }
    }
//如果是有父子间通信的时候就进入判断,如果没有父子间通信的时候就进入elseif,调用proxy()
//将this的上下文、data、data里面的key传进去
    if (props && hasOwn(props, key)) {
      process.env.NODE_ENV !== 'production' && warn(
        `The data property "${key}" is already declared as a prop. ` +
        `Use prop default value instead.`,
        vm
      )
    } else if (!isReserved(key)) {
      proxy(vm, `_data`, key);
    
  }
  // observe data
  observe(data, true /* asRootData */)
}
//proxy函数
  export function proxy (target: Object, sourceKey: string, key: string) {
//target也就是vm也就是this,soourceKey=_data
  sharedPropertyDefinition.get = function proxyGetter () {
    return this[sourceKey][key]
  }
  sharedPropertyDefinition.set = function proxySetter (val) {
    this[sourceKey][key] = val
  }
  Object.defineProperty(target, key, sharedPropertyDefinition)
}
    }
const sharedPropertyDefinition = {
  enumerable: true,
  configurable: true,
  get: noop,
  set: noop
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值