vue2.0源码解析,Data

源码

话不多说,直接放出源码。这里的整体代码也不多,我基本也已做了注释。

// 对于process.env.NODE_ENV !== 'production'可以忽略掉,都是开发时候的警告提示处理

function proxy (target: Object, sourceKey: string, key: string) {
  sharedPropertyDefinition.get = function proxyGetter () {
    return this[sourceKey][key]
  }
  sharedPropertyDefinition.set = function proxySetter (val) {
    this[sourceKey][key] = val
  }
  Object.defineProperty(target, key, sharedPropertyDefinition)
}

// Component 当前初始化的组件
function initData (vm: Component) {

  // 拿到options.data
  let data = vm.$options.data

  // 判断是否为函数,是则拿到返回结果,否则直接使用 》 data || {}
  // getData(data, vm): 拿到data对象的返回结果 
  data = vm._data = typeof data === 'function' ? getData(data, vm) : data || {}

  // isPlainObject 是否为一个原生对象,否则将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
  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]

    // 检查options.methods与data是否有重名方法
    if (process.env.NODE_ENV !== 'production') {
      if (methods && hasOwn(methods, key)) {
        warn(
          `Method "${key}" has already been defined as a data property.`,
          vm
        )
      }
    }

    // 检查options.props与data是否有重名方法
    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)) {
      // isReserved: 非 $和_开头

      // 将data里面的数据通过Object.defineProperty代理到vm上 vm._data.aa 可以vm.aa拿到
      proxy(vm, `_data`, key)
    }
  }

  // observe data
  // 响应式数据初始
  // asRootData: 是否为根数据
  observe(data, true /* asRootData */)
}

疑问

这是我看这段源码中的疑问,答出来,我觉得这段代码就可以算基本理解了。

Q、为什么data是一个函数
  • 因为组件的一个可复用特性,使得可以存在多个引用,而使用return出去可以保证每个组件都不互相影响,如果直接定义data: {…},则修改a处,会导致b一起被修改
Q、为什么调用proxy函数代理
  • 方便开发者,可以通过vm直接访问、修改操作,最终映射到 vm._data[key] 里面
// 非代理
vm.data.aaa

// 代理后
vm.aaa
  • 再次有个细节 isReserved 判断了非 $_ 开头的变量,避免和vm的内部变量方法冲突
Q、最后一行observe的作用
  • 调用此函数,初始化数据响应式监听
  • 具体流程可以参数我之前的博客,实现了简易版的响应式数据,基本流程跟vue源码中是一样的。
  • 实现vue2.0响应式原理
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值