讀懂原始碼 一步一步實現乙個 Vue

2021-09-02 14:51:15 字數 2164 閱讀 4861

原始碼閱讀:究竟怎樣才算是讀懂了?

市面上有很多原始碼分析的文章,就我看到的而言,基本的套路就是梳理流程,講一講每個模組的功能,整篇文章有一大半都是直接掛原始碼。我不禁懷疑,作者真的看懂了嗎?為什麼我看完後還是什麼都不懂呢?

事實上乙個經過無數次版本迭代的框架原始碼並不適合初學者直接閱讀,因為裡面有太多細節,太多噪點,太多枝枝蔓蔓。要想真正理解框架的核心邏輯,必須剝繭抽絲,還原出乙個純淨的雛形。如同 jquery 最早的版本只有六百多行,我相信 vue 的核心功能也只需要幾百行就能實現。所以,讀懂原始碼的標誌就是還原,碼越薄,真相就越清晰。

如何還原雛形?

一開始我設想的還原過程就是先刪後拆。什麼報錯資訊、引數校驗、非核心功能全部砍掉,八千行變成了五千行。然後再拆,按功能模組將乙個 vue.js 拆分成 util.js, observer.js, watcher.js …

理想狀態下,我應該能夠理解原始碼了吧,可做完解剖手術後,我發現裡面的邏輯依然紛繁複雜,剪不斷,理還亂,草蛇灰線,伏脈千里,即便換了乙個更早期更簡短的版本,仍然很快又陷入了永無止境的細節中。

定義核心

version:2.0.4

只考慮 runtime 版本,不考慮模板編譯,不考慮服務端渲染。

核心功能:響應式的資料繫結、虛擬 dom、diff 演算法、patch 方法(用於更新真實 dom)

目標

事實上,vue-cli 生成的專案中,標籤中的內容都會被編譯為 render 函式,render 函式返回整棵虛擬節點樹。我們最終要實現乙個 vue,來完成上面的示例。

當 new vue() 的時候發生了什麼?

我們的實現會參考原始碼的套路,但會大量的簡化其中的細節。為了理解原始碼的結構,最好的突破口就是了解程式的起點 new vue() 的背後究竟發生了什麼。

簡單梳理下原始碼的執行流:

=> 初始化生命週期

=> 初始化事件系統

=> 初始化state,依次處理 props、data、computed …

=> 開始渲染 _mount() => _render() 返回 vdom=> _update() => __patch__() 更新真實dom

第一步:將虛擬 dom 樹渲染到真實的 dom

每乙個 dom 節點都是乙個 node 物件,這個物件含有大量的屬性與方法,虛擬 dom 其實就是超輕量版的 node 物件。

我們要生成的 dom 樹看上去是這樣的:

關於 data 引數的屬性,請參考官方文件

隨後我們會通過 createelm 方法和 createchildren 方法的相互呼叫,遍歷整棵虛擬節點樹,生成真實的 dom 節點樹,最後替換到掛載點。

完整**

第二步:修改資料,執行 diff 演算法,並將變化的部分 patch 到真實 dom

diff 演算法的邏輯比較複雜,可以單獨摘出來研究,由於我們的目的是理解框架的核心邏輯,因此**實現裡只考慮了最簡單的情形。

完整**

第三步:對資料做響應式處理,當資料變化時,自動執行更新方法

data 中的每乙個屬性都會被處理為訪問器屬性,同時每乙個屬性都會在閉包中維護乙個屬於自己的 dep 物件,用於存放該屬性的依賴項。當屬性被賦予新的值時,就會觸發 set 方法,並通知所有依賴項進行更新。

完整**

vue 漸進式的特點,使其上手極其容易,我相信,漸進式的展現框架邏輯的實現過程,也會使理解變得更容易。

原文

一步一步實現FormsAuthentic驗證登入

本文不講原理,只講用法,原理性的東西網上特別多,不過還是會對一些要用到的東西進行解釋,不深入講原理。本文中用的是vs2012 net mvc 4.0。原理看這篇文章 看完這個文章絕對受益匪淺。說下登入的整個流程 使用者輸入賬號密碼 點選提交 資料提交到後台控制器 去資料庫取得使用者資料 如果登入成功...

一步一步實現乙個簡單的OS HelloWorld

先弄個helloworld吧,雖然這個網上一大堆,不過不知道的人還是不少,就簡單的弄乙個吧。系統啟動時,第一步是bios自檢 這個不管 然後從cmos中設定的預設引導介質中載入第乙個扇區 512位元組 到記憶體的0x07c00處 0x0000 0x7c00 之後,跳轉執行。所以,引導啟動系統的第一部...

一步一步 Sql Azure

一步一步 sql azure 1.使用 windowsazure 平台賬號登陸 2.新建sqlazure server 3.新建資料庫 4.為sql azure server 新增防火牆規則,只有將本機新增到規則裡才能從本機連線到該sqlazure server 5.連線到sql azure ser...