1. 程式人生 > 實用技巧 >Vue原始碼流程總結

Vue原始碼流程總結

1.Vue的初始化過程

1. 初始化生命週期

2. 初始化事件系統

3. 初始化state,依次處理props, methods, data, computed ...

export function initState(vm: Component) {
  const opts = vm.$options
  if (opts.props) initProps(vm, opts.props)              
  if (opts.methods) initMethods(vm, opts.methods)        
  if (opts.data) initData(vm)                            
  
if (opts.computed) initComputed(vm, opts.computed) if (opts.watch) initWatch(vm, opts.watch) } }
4. 開始渲染 _mount() => _render() => 返回vdom => _update() => _patch() 更新dom

2. Vue資料響應式原理

initData 初始化使用者資料

observe 將資料進行觀測

new Observer 定義觀測物件

this.walk(value) 迴圈處理物件的所有key

defineReactive 將物件的指定key定位為響應式

Object.defineProperty 在get和set方法種定義響應式,在get方法種用 Dep.depend 進行依賴收集
在set方法中用 dep.notify 進行依賴更新通知

3. Vue陣列變化檢測 對陣列型別的資料,進行方法重寫,將原陣列方法替換為自定義的同名方法,在自定義方法中呼叫原方法取值,並進行依賴更新通知。 依然是使用 dep.notify 方法 initData 初始化使用者資料 observe 觀測使用者資料 new Observer 定義觀測物件 protoAugment 將陣列的原型方法指向重寫的原型 重寫陣列的原型方法,並新增變更通知 深度觀測陣列中的每一項引用型別 4. Vue非同步渲染步驟
// src/core/observer/dep.js
let uid = 0            // Dep例項的id,為了方便去重

export default class Dep {
  static target: ?Watcher           // 當前是誰在進行依賴的收集
  id: number
  subs: Array<Watcher>              // 觀察者集合
 
  constructor() {
    this.id = uid++                             // Dep例項的id,為了方便去重
    this.subs = []                              // 儲存收集器中需要通知的Watcher
  }

  addSub(sub: Watcher) { ... }  /* 新增一個觀察者物件 */
  removeSub(sub: Watcher) { ... }  /* 移除一個觀察者物件 */
  depend() { ... }  /* 依賴收集,當存在Dep.target的時候把自己新增觀察者的依賴中 */
  notify() { ... }  /* 通知所有訂閱者 */
}

const targetStack = []           // watcher棧

export function pushTarget(_target: ?Watcher) { ... }  /* 將watcher觀察者例項設定給Dep.target,用以依賴收集。同時將該例項存入target棧中 */
export function popTarget() { ... }  /* 將觀察者例項從target棧中取出並設定給Dep.target */
pushTaget和popTarget是和Dep類同級的方法,直接暴露給其他類使用
dep.notify() dep通知更新 subs[i].update() dep中的watcher呼叫update方法 queueWatcher 將watcher加入到佇列中 nextTick(flushSchedulerQueue) 在下一個tick,flush佇列,執行所有的watcher方法 5. nextTick方法實現原理 nextTick(cb) nextTick方法傳入回撥 callbacks.push(cb) 陣列儲存所有回撥 timerFunc 在timerFunc中呼叫回撥,timerFunc是用microTask模擬的,例如Promise.then, MutationObserver,setImmedate,setTimeout等 返回Promise 可以執行then方法 6. Vue的computed實現過程 initComputed new Watcher defineComputed createComputedGetter 在此方法中進行依賴收集,和依賴計算,即執行watcher.evaluate方法 使用者取值 dirty = false 使用快取,返回上次結果,dirty = true watcher.evaluate(),重新計算結果 7. Vue的響應式更新過程 model更新 set方法 -> 觸發Dep.notify -> Dep的subs中的Watcher -> Watcher呼叫update -> queueWatcher -> nextTick -> flushQueueWatcher -> 生成新的Vnode -> 新VNode 與 老VNode 進行diff -> patch 將差異更新到檢視 diff是patch過程的核心。diff演算法有2個顯著特點: 1. 只會同級進行比較,不會垮層級比較 2. 在diff列表過程中,迴圈從兩邊向中間收攏 參考: https://blog.csdn.net/MrWeb/article/details/105781370 https://www.cnblogs.com/kidney/p/8018226.html