調試
閱讀源碼最好的方式還是通過調試,否則很容易在源碼裡迷失方向,本文提供了一種友善的方式來調試:
git clone https://github.com/wanglin2/learn_vue_2.6.0.git
cd
然後通路:
http://【你的ip:端口】/examples/index.html
即可打開測試頁面,測試檔案在
/examples/
目錄下,你可以修改
html
和
js
檔案,然後重新整理頁面即可。
引入vue時的初始化工作
首先
Vue
是存在很多建構版本的,我們要閱讀的是包含編譯器和運作時的
UMD
版本,對應打包後的檔案是
/dist/vue.js
,入口檔案是在
/src/platforms/web/entry-runtime-with-compiler.js
,這個檔案主要是定義了
Vue
在
web
環境下的
$mount
方法。
Vue
對象是從
./runtime/index
檔案引入的,這個檔案主要是添加一些特定平台的方法,比如一些工具方法:
Vue.config.mustUseProp = mustUseProp
// ...
添加平台運作時指令(v-model、v-show)群組件(Transition、TransitionGroup):
extend(Vue.options.directives, platformDirectives)
extend(Vue.options.components, platformComponents)
給原型添加
__patch__
和
$mount
方法:
Vue.prototype.__patch__ = inBrowser ? patch : noop
Vue.prototype.$mount = function
Vue
構造函數依舊是從其他檔案引入的:
core/index.js
,這個檔案裡做的事情比較多,首先執行了
initGlobalAPI
方法,把全局配置對象挂載到
Vue
上:
const configDef = {}
configDef.get = () => config
Object.defineProperty(Vue, 'config', configDef)
然後添加了一些内部使用的工具方法:
Vue.util = {
warn,
extend,
mergeOptions,
defineReactive
}
接着添加了
set
、
delete
等靜态方法:
Vue.set = set
Vue.delete = del
Vue.nextTick = nextTick
// 2.6版本起開始暴露響應方法
Vue.observable = (obj) => {
observe(obj)
return
然後添加了一個選項對象,并添加了三個屬性,就是我們熟悉的
component
、
directives
、
filters
,并給
components
挂載了
keep-alive
元件:
Vue.options = Object.create(null)
ASSET_TYPES.forEach(type {
Vue.options[type + 's'] = Object.create(null)
})
Vue.options._base = Vue
// 挂載keep-alive元件
extend
是一個簡單的淺拷貝方法,在
vue
内部的出鏡率非常高:
export function extend (to, _from) {
for (const key in _from) {
to[key] = _from[key]
}
return
最後又添加了一堆靜态方法:
Vue.use
、
Vue.mixin
、
Vue.extend
、
Vue.component
、
Vue.filter
、
Vue.directive
。
Vue
構造函數依然不是在該檔案定義的,讓我們最後再跳到
core/instance/index.js
,在這裡終于看到了
Vue
構造函數的廬山真面目:
function Vue (options) {
this._init(options)
}
// 添加_init方法
initMixin(Vue)
// 代理data和prop資料、定義$set、$delete、$watch方法
stateMixin(Vue)
// 添加$on、$once、$off、$emit方法
eventsMixin(Vue)
// 添加_update、$forceUpdate、$destroy方法
lifecycleMixin(Vue)
// 添加一些建立VNode的快捷方法、$nextTick、_render方法