一、為什么Vue實(shí)例化后,通過this.能獲取到data內(nèi)的數(shù)據(jù)

一. 從github獲取vue開發(fā)版本的源碼

git clone https://github.com/vuejs/vue.git

二. 從實(shí)例化vue (new vue)開始講解

想了解“為什么Vue實(shí)例化后,通過this.能獲取到data內(nèi)的數(shù)據(jù)”必須對(duì)call函數(shù)內(nèi)置方法有所了解,如有認(rèn)識(shí)模糊的話可以參考JS的call方法的作用解釋,簡(jiǎn)單易懂

1. new 實(shí)例化Vue首先進(jìn)入的src/core/instance/index.js

// vue其實(shí)就是 function 實(shí)現(xiàn)的 class
function Vue (options) {
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword')
  }
  // new Vue進(jìn)行初始化 Vue 并將options 參數(shù)傳入_init 內(nèi) ,this._init 是原型中的方法 ,這個(gè)init方法來自于 ‘./init’ 中
  this._init(options)
}

在實(shí)例化時(shí),執(zhí)行this._init(options),這個(gè)_init內(nèi)置方法是下面initMixin(Vue)增加的

2. 進(jìn)入src/core/instance/init.js 查看initMixin方法

initState(vm) // 初始化狀態(tài)(這個(gè)狀態(tài)包含data props methods), 這個(gè)初始化解決了實(shí)例化是通過 this 獲取 data 

3. 進(jìn)入src/core/instance/state.js查看initState方法

initData(vm)就是Vue實(shí)例化后,初始化data 通過this.能獲取到data內(nèi)的數(shù)據(jù)

// 初始化狀態(tài)(這個(gè)狀態(tài)包含data props methods), 這個(gè)初始化解決了實(shí)例化是通過 this 獲取 data props methods 內(nèi)數(shù)據(jù)
export function initState (vm: Component) {
  vm._watchers = []
  const opts = vm.$options
  if (opts.props) initProps(vm, opts.props)
  if (opts.methods) initMethods(vm, opts.methods)
  if (opts.data) {
    // 初始化data
    initData(vm)
  } else { 
    observe(vm._data = {}, true /* asRootData */)
  }
  if (opts.computed) initComputed(vm, opts.computed)
  if (opts.watch && opts.watch !== nativeWatch) {
    initWatch(vm, opts.watch)
  }
}

initMixin內(nèi)執(zhí)行了initState,初始化data數(shù)據(jù)

function initData (vm: Component) {
  let data = vm.$options.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
    )
  }
  // 對(duì)比props methods data中的 key 是否相同 如果相同報(bào)出警告  禁止相同
  // 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 (process.env.NODE_ENV !== 'production') {
      if (methods && hasOwn(methods, key)) {
        warn(
          `Method "${key}" has already been defined as a data property.`,
          vm
        )
      }
    }
    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 */)
}

initData 方法中g(shù)etData將就是實(shí)現(xiàn)Vue實(shí)例化后,通過this.能獲取到data內(nèi)的數(shù)據(jù)

data = vm._data = typeof data === 'function'
    ? getData(data, vm)
    : data || {}

我們?cè)倏纯?getData方法是怎樣實(shí)現(xiàn)Vue實(shí)例化后,通過this.能獲取到data內(nèi)的數(shù)據(jù)

export function getData (data: Function, vm: Component): any {
  // #7573 disable dep collection when invoking data getters
  pushTarget()
  try {
    // data 函數(shù)執(zhí)行的時(shí)候?qū)?return 內(nèi)的數(shù)據(jù) 返回出來 vm函數(shù)可以通過 this. 獲取到data 內(nèi)的數(shù)據(jù) ,也就是我們?cè)趯?shí)例的時(shí)候?qū)?this. 能獲取到data 內(nèi)數(shù)據(jù)原因
    return data.call(vm, vm)
  } catch (e) {
    handleError(e, vm, `data()`)
    return {}
  } finally {
    popTarget()
  }
}

三、總結(jié)

不賣關(guān)子啦!其實(shí)Vue實(shí)例化的時(shí)候,通過getData方法中call修改this指針來實(shí)現(xiàn)Vue實(shí)例后能獲取到data體內(nèi)的數(shù)據(jù),小伙伴可能感覺認(rèn)為我將vue初始化部分流程拉出來是的你越來越糊涂,但是如果我不講上面的代碼拉出來,我直接來這句總結(jié),你會(huì)更加懵的??????

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容