new Vue()的過程
new Vue()的大致流程
new Vue() => _init() => $mount() => mountComponent() => new Watcher() => updateComponent() => render() => _update()
用戶調用 new Vue(options) 實例化 Vue,Vue 在 _init 方法中初始化相關字段和事件,最重要的,建立起響應式系統,Vue 實例的后續運行重度依賴於此響應式系統。Vue 會新建一個【觀察者】,該觀察者在創建時會執行 update 方法首次渲染視圖,包含 Vue 指令的模板會被替換成編譯后的朴素 HTML。Vue 會遍歷傳入的 data 選項,通過 Object.defineProperty 設置 setter 和 getter 將其變成【被觀察對象】。當 data 的數據發生變化時,被觀察對象就會通知觀察者,觀察者就會再次調用 update 方法打補丁式地更新視圖。
簡版過程
=> _init() : Vue構造函數constructor()中進行初始化:主要進行
- initLifecircle :
$parent /$root / $children - initEvents: 事件監聽
- initRender:
slot / $createElment() - callHook(vm, 'beforeCreate'):組件創建之前的鈎子
- initInjections: 注入祖輩傳遞的數據
- initState: ☆ 組件數據初始化,包括 props、data、methods、computed、watch。 數據響應式:data中一個key就一個Dep實例
- initProvide:在data等之后再進行輸出 provide
- callHook(vm, 'created'): create生命周期完成
=> $mount(): 初始化完成之后,進行掛載。如果我當前執行的是編輯器的版本,用的模板字符串的方式去申明的模板,那我就需要進行編譯
=> mountComponent():編譯完成,就會調用mountComponent方法。這個方法中主要做兩件事:1. 申明一個updateComponent方法。 2. 創建一個Watcher實例,和當前組件之間產生一個1對1的關系,這個watcher需要初始化或者更新updateComponent這個方法
-
=> new Watcher():
是在數據初始化之后,即在created鈎子函數之后,mounted鈎子函數之前進行Watcher實例化。
跟當前組件產生1對1的關系。這個watcher實例的作用是:初始化或者更新 updateComponent這個函數。在初始化的時候會執行updateComponent函數, 當watcher管理的數據發生變化的時候,updateComponent方法就會再次執行。由於這個wathcer關聯的是當前的這個組件實例,這個組件內部的任何值發生變化,這個updateComponent方法都會執行。
-
=> updateComponent():
- => render(): 獲取虛擬Dom
- => _update():轉為真實dom:初始化el,或者通過
__patch__(即diff算法)進行更新
updateComponent這個方法執行的時候,會先執行render方法,得到虛擬dom,再把vdom作為參數傳給_update,讓 _update執行比對。
如果_update首次進行比對的時候,顯然,首次vdom是不存在的,所以進行初始化操作,批量創建,直接追加。
如果是后期的更新操作,由於有新舊vdom,就要進行比對,進行diff操作。
