手寫Vue2 0原始碼 渲染更新原理

2022-07-03 02:45:13 字數 3580 閱讀 5405

### 前言

此篇主要手寫 vue2.0 原始碼-**渲染更新原理**

採用觀察者模式 定義 watcher 和 dep 完成依賴收集和派發更新 從而實現渲染更新.

**適用人群:** 沒時間去看官方原始碼或者看原始碼看的比較懵而不想去看的同學

### 正文

// 我們在這裡模擬更新

settimeout(() => , 1000);

```#### 1.定義 watcher

```// src/observer/watcher.js

// 全域性變數id 每次new watcher都會自增

let id = 0;

export default class watcher

// 例項化就會預設呼叫get方法

this.get();

}get()

}```

在 observer 資料夾下新建 watcher.js 代表和觀察者相關 這裡首先介紹 vue 裡面使用到的[觀察者模式]( 我們可以把 watcher 當做觀察者 它需要訂閱資料的變動 當資料變動之後 通知它去執行某些方法 其實本質就是乙個建構函式 初始化的時候會去執行 get 方法

#### 2.建立渲染 watcher

```// src/lifecycle.js

export function mountcomponent(vm, el) ;

new watcher(vm, updatecomponent, null, true);

}```

我們在元件掛載方法裡面 定義乙個渲染 watcher 主要功能就是執行核心渲染頁面的方法

#### 3.定義 dep

```// src/observer/dep.js

// dep和watcher是多對多的關係

// 每個屬性都有自己的dep

let id = 0; //dep例項的唯一標識

export default class dep

}// 預設dep.target為null

dep.target = null;

```dep 也是乙個建構函式 可以把他理解為觀察者模式裡面的被觀察者 在 subs 裡面收集 watcher 當資料變動的時候通知自身 subs 所有的 watcher 更新

dep.target 是乙個全域性 watcher 指向 初始狀態是 null

#### 4.物件的依賴收集

```// src/observer/index.js

// object.defineproperty資料劫持核心 相容性在ie9以及以上

function definereactive(data, key, value)

return value;

},set(newvalue) ,

});}

```上訴**就是依賴收集和派發更新的核心 其實就是在資料被訪問的時候 把我們定義好的渲染 watcher 放到 dep 的 subs 陣列裡面 同時把 dep 例項物件也放到渲染 watcher 裡面去 資料更新時就可以通知 dep 的 subs 儲存的 watcher 更新

#### 5.完善 watcher

```// src/observer/watcher.js

import from "./dep";

// 全域性變數id 每次new watcher都會自增

let id = 0;

export default class watcher

// 例項化就會預設呼叫get方法

this.get();

}get()

// 把dep放到deps裡面 同時保證同乙個dep只被儲存到watcher一次 同樣的 同乙個watcher也只會儲存在dep一次

adddep(dep)

}// 這裡簡單的就執行以下get方法 之後涉及到計算屬性就不一樣了

update()

}```

watcher 在呼叫 getter 方法前後分別把自身賦值給 dep.target 方便進行依賴收集 update 方法用來更新

#### 6.完善 dep

```// src/observer/dep.js

// dep和watcher是多對多的關係

// 每個屬性都有自己的dep

let id = 0; //dep例項的唯一標識

export default class dep

depend()

}notify()

addsub(watcher)

}// 預設dep.target為null

dep.target = null;

// 棧結構用來存watcher

const targetstack = ;

export function pushtarget(watcher)

export function poptarget()

```定義相關的方法把收集依賴的同時把自身也放到 watcher 的 deps 容器裡面去

> 思考? 這時物件的更新已經可以滿足了 但是如果是陣列 類似 a.push(4) 並不會觸發自動更新 因為我們陣列並沒有收集依賴

#### 7.陣列的依賴收集

```// src/observer/index.js

// object.defineproperty資料劫持核心 相容性在ie9以及以上

function definereactive(data, key, value) 屬性a對應的值是乙個陣列 觀測陣列的返回值就是對應陣列的observer例項物件

childob.dep.depend();

if (array.isarray(value)) 這種陣列多層巢狀 陣列包含陣列的情況 那麼我們訪問a的時候 只是對第一層的陣列進行了依賴收集 裡面的陣列因為沒訪問到 所以五大收集依賴 但是如果我們改變了a裡面的第二層陣列的值 是需要更新頁面的 所以需要對陣列遞迴進行依賴收集

if (array.isarray(value)) }}

}return value;

},set(newvalue) ,

});}

// 遞迴收集陣列依賴

function dependarray(value) }}

```如果物件屬性的值是乙個陣列 那麼執行 childob.dep.depend()收集陣列的依賴 如果陣列裡面還包含陣列 需要遞迴遍歷收集 因為只有訪問資料觸發了 get 才會去收集依賴 一開始只是遞迴對資料進行響應式處理無法收集依賴 這兩點需要分清

#### 8.陣列的派發更新

```// src/observer/array.js

關鍵**就是 ob.dep.notify()

#### 9.渲染更新的思維導圖

![渲染更新](

## 小結

![整體流程](

這裡放一張 整個 vue 響應式原理的 咱們從資料劫持-->模板解析-->模板渲染-->資料變化檢視自動更新整個流程已經手寫了一遍 尤其是此篇介紹的渲染更新相關的知識點 建議反覆理解原理之後自己動手實現一遍 因為vue 很多核心原理和 api 都跟這裡的知識點相關哈

> 最後如果覺得本文有幫助 記得**點贊三連**哦 十分感謝!

手寫Vue2 0原始碼 渲染更新原理

此篇主要手寫 vue2.0 原始碼 渲染更新原理 採用觀察者模式 定義 watcher 和 dep 完成依賴收集和派發更新 從而實現渲染更新.適用人群 沒時間去看官方原始碼或者看原始碼看的比較懵而不想去看的同學 1.定義 watcher src observer watcher.js 全域性變數id...

手寫Vue2 0原始碼 渲染更新原理

此篇主要手寫 vue2.0 原始碼 渲染更新原理 採用觀察者模式 定義 watcher 和 dep 完成依賴收集和派發更新 從而實現渲染更新.適用人群 沒時間去看官方原始碼或者看原始碼看的比較懵而不想去看的同學 1.定義 watcher src observer watcher.js 全域性變數id...

vue2 0原始碼學習一(vue原始碼構建過程)

前提知識背景 vue.js的打包構建是基於rollup進行的 1.開啟專案的package.json,在裡面可以看到很多配置項以及命令,今天先學習 的構建,需要關注下圖地方 這裡使用的build命令就是平時在使用vue cli打包的時候觸發的命令,可以看到它其實是執行了乙個node程式,執行scri...