vue之this.name 触发流程分析

137 阅读1分钟

前言

使用vue更新data的时候,一般都是使用this.name='zzf'命令,但是为什么这么写会触发更新呢,一直不是很了解。今天阅读2.6.12版本源码,有对这个有进一步的理解,在此做个笔记。

更新name数据

分析this.name数据到底访问什么

在src/code/instance/state.js中有一个stateMixin,这个给出了问题的答案。

const dataDef = {}
dataDef.get = function () { return this._data }
Object.defineProperty(Vue.prototype, '$data', dataDef)

通过代码分析,访问this.name,实际上时访问this._data.name。

那this._data跟options的data函数又有什么关系呢?

在src/code/instance/state.js中有一个initData函数,里面有对this._data的一个操作。

function initData (vm: Component) {
  let data = vm.$options.data
  data = vm._data = typeof data === 'function'
    ? getData(data, vm)
    : data || {}  // 核心就是这里,对options的data函数进行执行,返回的结果存放在vm._data上,后续再监听vm._data,这样子就可以触发更新了
  if (!isPlainObject(data)) {
    data = {}
  }
  // 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]
    if (props && hasOwn(props, key)) {
    } else if (!isReserved(key)) {
      proxy(vm, `_data`, key)
    }
  }
  // observe data
  observe(data, true /* asRootData */) // 监听data数据
}

一开始以为vm.$options.data跟vm._data是同一个对象,后来发现不是同一个对象,_data是options.data函数的执行结果;一开始以为就监听的是options.data对象,后来看到代码才反应过来,监听的是_data对象。(搞混淆了)

总结

所以更新this.name,实际上是更新this._data.name。