render
函數。
一、我們到 vue倉庫 下載 Vue2.6.14 的源碼。


二、首先通過 package.json
中的打包命令,我們可以找到完整版的 Vue 的入口文件。
在該文件中,看到vue用的是的rollup編輯的
rollup -w - c
--wacth | -w 開啟文件監視 // 它檢測到磁盤上單個模塊已經改變,它會重新構建你的文件束
--config | -c 指定配置文件地址
(1)package.json
(2)scripts/config.js
找到config.js文件,路徑為scripts/config.js
需要拿到 --environment傳入的環境變量,根據配置TARGET的配置選擇 web-full-dev的配置
找到resole的封裝找到對應的路徑配置alias.js
(3)scripts/alias.js
(4)src/platforms/web/entry-runtime-with-compiler.js
所以我們先來到 src/platforms/web/entry-runtime-with-compiler.js
文件
通過一層一層的分析,終於快要到vue的核心代碼了
簡單來看下,這個文件主要是擴展了 Vue.prototype.$mount
方法
根據源碼,我們還可以得到一個小知識,就是如果 Vue 的 options 中同時傳入 el, render, template,哪個優先級最高?
通過下面這段代碼,我們可以發現,render
的優先級是最高的,因為如果是 render
,則直接走到最下面的 mount
了,其次是 template
,然后再是 el
。
在src/platforms/web/entry-runtime-with-compiler.js
這個文件中看到引入的vue
也就是這個文件src/platforms/web/runtime/index.js
文件
(5)src/platforms/web/runtime/index.js
這里有 2 個比較重要的方法
可以看到,原始的 $mount
是在這里被賦值的,不過我們還沒找到初始的 Vue
類,所以我們繼續進入 src/core/index.js
(6) src/core/index.js
initGlobalAPI
定義了一些全局 API,比如 set
,use
之類的,我們繼續看 instance/index
中的代碼。
三、原始的 Vue
(7) src/core/instance/index.js
在這里,終於找到原始的 Vue
了
構造函數定義了一個Vue
new Vue
的入口就是這里。
它調用了 _init
方法,而 _init
方法是 initMixin
混入進來的。
找到initMixin
(8) src/core/instance/init.js
在這里,可以看到Vue 的初始化過程
看一下源碼中的 initState
(9)src/core/instance/state.js
可以看到數據響應式的做法,初始化處理 data
的函數 initData()
這個 initData方法調用了proxy
和 observe
(10)src/core/observer/index.js
來看看observe
在構造函數中,發現每個被處理過的對象,都會掛上 _ob_
這個 key
,代表着 Observer
實例,
另外 this.dep = new Dep()
這個代碼要關注下,即每個 Observer
有一個獨有的 dep
依賴。
(11) src/core/instance/lifecycle.js
Watcher
每個組件只有一個 Watcher
,當然用戶也可能通過 watch
創建額外的。這里我們也可以看到組件的掛載過程,先調用 render
函數,那 render
生成虛擬 DOM,然后交給 _update
函數。
看下 _update
函數的邏輯,可以看到就是使用 _patch_
來對比前后虛擬 DOM,然后生成真實 DOM,再進行渲染,patch
也就是我們常說的 diff
。
(12) src/core/observer/watcher.js
從構造函數中可以發現 this.get
方法的調用,pushTarget
用來設置 Dep.target
,this.getter
則是調用了傳進來的更新函數