Vue.js源碼分析(一)--init

前言

vue源碼相對於React還是要簡單一些的,今天開始踩這個坑,幫助我更好的去理解Vue深層的東西,也能更好的看懂Vue3吧。

init

首先,當我們new Vue時,會調用this._init方法,而這個方法是在initMixin裏面定義的:

export function initMixin (Vue: Class<Component>) {
  Vue.prototype._init = function (options?: Object) {
    const vm: Component = this
...

這裏面先後定義uid,合併options,初始化生命週期,事件中心,render函數等。

vm._uid = uid++
...
vm.$options = mergeOptions(...)
initLifecycle(vm)
initEvents(vm)
initRender(vm)
initState(vm)
。。。

最後如果存在el:

    if (vm.$options.el) {
      vm.$mount(vm.$options.el)
    }

就會把這個對象掛載到DOM上渲染出來,而這個mount也是這個階段最重要的方法。

initState

接着我們從疑問出發,我們知道當我們在data裏面定義數據之後,是可以通過this.xxx訪問到的,那麼這一步是如何實現的呢?

這裏我們需要關注initState:

  const opts = vm.$options
  if (opts.props) initProps(vm, opts.props)
  if (opts.methods) initMethods(vm, opts.methods)
  if (opts.data) {
    initData(vm)
  }

前面如果有props和method,那麼調用初始化方法,這裏重點看initData。
首先是拿到data:

  let data = vm.$options.data

接着還要賦值vm._data方便後面調用,然後看data是不是function類型,是的話就調用getData方法,裏面執行:

data = vm._data = typeof data === 'function'?...:...
...
data.call(vm, vm)

接着會判斷props裏面是不是使用到了data返回的對象的鍵值,畢竟他們都會被掛載到vm上。

最後會調用proxy方法:

      proxy(vm, `_data`, key)

這裏做了一層代理:

export 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)
}

當我們訪問vm.key,即this.key時,就會走前面的get方法,即vm._data.key。也就是說我們訪問this.key時,實際訪問的是this._data.key。

同理,其實props也是這麼做的。this._props.key。

這裏沒有介紹響應式處理,initState也中還有這一重要部分。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章