【Vue原理】Vue源碼閱讀總結大會

專一 Vue 源碼分享,爲了方便你們理解,分爲了白話版和 源碼版,白話版能夠輕鬆理解工做原理和設計思想,源碼版能夠更清楚內部操做和 Vue的美,喜歡我就關注個人公衆號,好吧兄弟,不會讓你失望的node

閱讀源碼是須要不少的勇氣的,特別是對這種 Vue 源碼的框架,十分抽象,使用了好多設計模式,封裝得十分精密。很難短期內能看得明白。設計模式

而我顯然也是作好了內心準備 和 知識準備啦數組

我老早就想攻破 Vue 源碼 這座城堡緩存

可是顯然我當時尚未作好準備,我認爲本身不能夠貿然去看,否則本身煩,本身累,還難以收穫閉包

本篇文章算是一個簡單地吹水,就是跟你們談談個人感想,沒有什麼知識含量,其實也有的。app

閱讀源碼準備了什麼

一、掌握 Vue 全部API

我把 Vue 的全部 API 都詳細研究使用過了一遍,並且儘可能在項目中都有使用,讓本身有深一點的體會框架

並且我對着官方文檔,一個個作了詳細的筆記,並且聯想過了使用場景。dom

二、JavaScript 紮實基礎

幸虧本身以前花了大力氣去給本身打基礎,讓本身如今的 JavaScript 基礎還算不錯。函數

逼着本身把不少本 JavaScript 書都看完了,而且作了詳細筆記。像是【 JavaScript易維護】【JavaScript性能 】,【JavaScript 高級程序設計】【巴菲特給股東的信】看了兩遍,說不上精通,也算是還能夠?性能

三、看完 JavaScript 設計模式

光是 JavaScript 設計模式 這本書 我就看了一年半,不能說本身把全部設計模式都掌握了,掌握了大部分吧,設計模式港真真的頗有趣,否則我也不會決心學

在這裏推薦 張容銘的 【JavaScript設計模式】,書講得很是透徹和詳細,我是從徹底不懂開始看的

也常用一部分,我一直以設計模式爲個人項目基構。就是 能用設計模式的地方,我都儘可能使用設計模式。

設計模式看起來就像是 劍客 的劍譜,有招有式,連人家武俠劇發功的時候都知道 喊出 招式的名字... 降龍十八掌!!!!

野路子難登大雅之堂,主要是很差看啊,代碼爲了好維護,易擴展

四、學會調試

我很大膽地說,若是你不會調試,你看 Vue 源碼,或者你會想死,你會出現這個場景...

MMP,這個方法是怎麼跳到 那個方法的,那個方法和 這個方法又是怎麼聯繫起來的?

也許你能夠慢慢 使用 函數名字 去尋找,可是無疑你會多消耗幾倍時間,並且你會更煩

使用調試真的方便,之前我也真的不喜歡調試,以爲好像很難???

更喜歡使用 console.log 去打印信息.....

是啊,我本身寫項目的時候,我仍是會使用 console.log 去調試.......

那是由於我本身代碼,我知道怎麼跑,你 看別人的代碼,仍是超級抽象的框架,使用 console.log 的方式.....

放心,相信我,你會掉不少頭髮.........

這裏,我使用的是 VSCode 去調試,真的簡單又方便,我當時也真的很難去讓本身又要學一個東西

可是我咬咬牙,我仍是學了,感謝本身......

我能夠保證,你從不懂到掌握,只要不到十分鐘,簡直就是 現實版的 十分鐘精通到入門

好吧,下面開始說,Vue 的簡單總結。

Vue 源碼的簡短的總結

一、封裝了不少經常使用的函數!

爲了 複用 且 易維護

經常使用的類型判斷、 類型轉換 、數據格式轉換(數組轉對象).....

舉些例子

function isObject(obj) {    return obj !== null && typeof obj === 'object'}
function isUndef(v) {    return v === undefined || v === null}
function isDef(v) {    return v !== undefined && v !== null}
function toString(val) {    
    return val == null ?    '' :    
    typeof val === 'object' ?    
    JSON.stringify(val, null, 2) :    String(val)
}
function toObject(arr) {    
    var res = {};    
    for (var i = 0; i < arr.length; i++) {        
        if (arr[i]) {
            extend(res, arr[i]);
        }
    }    return res
}
....

你說說不定過了幾年,判斷是不是一個對象,再也不是 什麼 typeof obj=="object"

若是沒有封裝,那豈不是全部代碼涉及到的都要改一遍,且不說若是有不少個都變了.....那你就頭大了

節點操做兼容函數

addClass ,removeClass,createElement,appendChild,removeChild

function addClass(el, cls) {    
    if (!cls || !(cls = cls.trim())) return
    if (el.classList) {        
        if (cls.indexOf(' ') > -1) {
            cls.split(/\s+/).forEach(function(c) { return el.classList.add(c); });
        } else {
            el.classList.add(cls);
        }

    } else {        
       var cur = " " + (el.getAttribute('class') || '') + " ";        
       if (cur.indexOf(' ' + cls + ' ') < 0) {
            el.setAttribute('class', (cur + cls).trim());
       }
    }
}
....

這些函數都頗有用,因此我都記下來了,畢竟是 框架封裝的,確定是最完善的

二、真的用了不少設計模式

就我看到的設計模式就有

觀察者模式、狀態模式、節流模式、 參與者模式、備忘錄模式、單例模式 裝飾者模式、組合繼承模式、鏈模式.........

我懷疑 Vue 把全部的設計模式都用完了.... 真的..... 若是你不懂設計模式

你真不會領悟到他這麼寫的精髓

我就選 Vue 經常使用的一個設計模式來說

【參與者模式】

Vue 封裝的不少函數都是用了 參與者模式,也能夠叫作柯里化

先來簡單解釋下 參與者模式

一、保存第一次調用 傳入參數

二、返回定製函數,函數內使用 參數

簡單實現像這樣

function add(a){    
    return function(b){ return a+b }
}
// 爲了定製函數,把第一次調用時的參數閉包保存
add5 = add(5)var result  = add5(9)

看一下 Vue其中一個 使用柯里化 的封裝函數

makeMap

建立 對象 map,返回函數,用於後面查找 某個東西是否存在 map 中

function makeMap( str,  expectsLowerCase ) {    
    var map = Object.create(null);   
    var list = str.split(',');    
    for (var i = 0; i < list.length; i++) {
        map[list[i]] = true;
    }    
    return expectsLowerCase ?        
        function(val) { return map[val.toLowerCase()]; } :        
        function(val) { return map[val]; }
}
        
// 應用
var isUnaryTag = makeMap(   
 'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' +  
 'link,meta,param,source,track,wbr');
 
// 查找 area 標籤是否存在 上面保存過的 字符串中
isUnaryTag('area')

三、使用不少閉包!

據我看過的地方

一、解析組件模板 使用了閉包做爲緩存,爲了重複解析

二、cached 函數,一個專門使用閉包 爲緩存的函數

三、上面所講到 的 柯里化全部涉及的函數,makeMap,parthPath,

四、createPatchFunction 當屬篇幅最大的使用閉包的函數了,把一堆函數做爲閉包,而後返回 一個函數。他最大的做用是 比較更新DOM 節點

四、使用不少標誌位

Vue 經常使用標誌位來

一、代表是否已經作了某件事

_isMounted:dom 是否已經掛載

_isDestroyed :組件是否已經摧毀

pending:代表更新回調的 setTimeout 已經執行

waiting:是否已經初始化更新隊列,在等待新的成員進入對壘

flushing:更新隊列是否已經開始逐個更新成員

......

二、指明當前東西的身份

isStatic:是不是靜態節點

isComment:是不是註釋節點

isCloned:是不是克隆節點

isOnce:是否有v-once 指令(若是有當前指令,會跳過編譯)

_isComponent:是不是組件

.....

多用標誌位,控制流程,替代多餘的判斷(直接判斷標誌位來確認身份,不用作太多的判斷),減小開銷

上面那些變量,你們沒看源碼,可能有些懵逼,不要緊,就當先知道有這個東西就行了

Vue 源碼分幾步走

我給本身定的任務是 分爲兩個部分

Vue 的主體內容

一、依賴收集 二、依賴更新 三、Virtual DOM ,dom 節點 生成虛擬Vnode 節點 四、Compile, 模板編譯 五、Diff、Patch, 節點比較更新 六、NextTick ,延遲執行回調 七、Render, 渲染機制 八、LifeCircle ,生命週期 九、Model ,雙向綁定 十、Event ,事件機制

Vue 組件選項

一、computed 二、filter 三、mixin 四、directive 五、slot 六、props 七、watch

我就大約以這些爲個人學習目標進行 源碼閱讀的,每一塊都是一個很是大的內容,每一塊內容都不是幾天能看完的,有時候還須要一點靈感。固然還有不少內容,可是個人目標也並非所有,一字不漏讀完,我要的是他的精髓便可,或許等我掌握了這些,再去開發其餘的內容,這樣或許更簡單

反正我始終提醒本身不要焦躁,由於這個東西真的是急不來,長期以往,不要妄想一步登天,一開始總會很難,可是久了也同樣很難,哈哈哈哈哈

若是你有興趣也讀源碼,咱們能夠一塊兒討論學習....

最後

源碼我也沒有看完,看了大概四個月,腦子漲得很,也就大概看了 百分之六七十吧,剩下一些打算慢慢看,真的裝不下了.....

而我也打算本身出一個Vue 源碼系列,算是把本身的閱讀心得再二次總結若是你也有興趣跟我一塊兒閱讀源碼,就加入我吧,關注個人公衆號哦,文章排版會好看不少

公衆號

相關文章
相關標籤/搜索