天天看點

Vue源碼筆記本(一)

(該文章對src/core/instance下的檔案的代碼功能做了注解,便于大家在看源碼過程中快速了解)

入口檔案 src/core/instance/index.js 中可以看到

vue的構造函數在此, 然後通過mixin的方式将

資料方法等特性處理(state)

事件處理(events)

生命周期(lifecycle)

渲染函數(render)

的相關的方法挂到vue的原型上去。

挂上了_init 方法,沒錯就是 構造函數當中調用的_init方法。

這裡做了一些參數處理,其中作者在參數對象指派的時候,用一個個指派代替列舉指派來提升性能。 這樣注釋的: // doing this because it's faster than dynamic enumeration.

然後就是依次執行以下方法,包括各個init函數和觸發鈎子

initstate一共做了如下操作

initprops和initdata的處理類似:

initprops做了類型檢驗,做了definereactive就是響應式處理;

initdata做了函數處理(data是對象或者函數),然後檢查key是否與props重複,還檢查了key是否$ 或者 _ 開頭,這是vue内部使用, 如果你的key以此開頭,你就會拿不到你的key了(這個好像沒看到說明,感覺可以提示下)

然後做了個proxy,把使用者參數props和data分别代理到 _props 和 _data 這2個内部屬性,使用者通路其實通路到了_props和_data下。

initmethods 這個就是把methods内部的函數bind到執行個體然後挂到執行個體

initwatch 通過周遊然後執行$watch方法來處理

initcomputed 周遊為建立一個 watcher 執行個體,然後放到_computedwatchers

(響應式相關後續再展開)

statemixin 混入方法挂了$data,$props,$set,$delete等讓資料操作指向_data 和 _props,然後挂了$watch 方法

挂載$on,$once,$off,$emit 四個方法

事件句柄都儲存在 _events 這個屬性裡,在$on方法裡做了個處理,判斷該執行個體是否有使用生命周期的hook,如果沒有_hashookevent這個值是false,然後在lifecycle的callhook方法裡将不會$emit生命周期hook,是一個性能優化。

在原型上挂上 _mount 方法,這個比較重要, $mount 用的就是方法, ($mount在上面的init函數被調用)這個方法運作的時候需要用到render函數裡了,沒有會報錯(關于這點,vue會把template或者el裡的html模版最終轉成render函數,一般如果我們用vue-loader開發,已經把template裡的内容轉成了render函數,是以最後打包出來的不會含有轉化template的功能代碼),render函數傳回的是一個vnode,下面貼個_mount部分代碼:

這裡可以看到2個生命周期了

_update 方法開始去做dom更新了,看_update方法

一開始用_ismounted判斷是否觸發beforeupdate鈎子,因為第一次插入dom也是調用這個方法,但是不應該觸發beforeupdate

然後就去調用 patch 方法去做diff 然後更新dom了。(vnode以後再看)

另外,還挂載了$forceupdate和$destroy 這2個方法

先挂載了 $nexttick 方法.

然後在rendermixin函數内往原型挂載了_render 方法(在instancei 下有個render-helpers檔案夾裡面有處理render相關的工具函數供調用)這個方法做了slot相關的操作,然後調用render函數拿到vnode ( render 相關的需要具體展開)

這裡有個_renderproxy ,在非生産環境下做了proxy,看 proxy.js ,就是在通路執行個體屬性的時候,通路不存在的屬性的時候給予提示.

以上。

繼續閱讀