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

寫文章不容易,點個讚唄兄弟
專一 Vue 源碼分享,文章分爲白話版和 源碼版,白話版助於理解工做原理,源碼版助於瞭解內部詳情,讓咱們一塊兒學習吧
研究基於 Vue版本 【2.5.17】

若是你以爲排版難看,請點擊 下面連接 或者 拉到 下面關注公衆號也能夠吧javascript

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

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

而我顯然也是作好了內心準備 和 知識準備啦,我老早就想攻破 Vue 源碼 這座城堡設計模式

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

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


閱讀源碼準備了什麼

一、掌握 Vue 全部API
我把 Vue 的全部 API 都詳細研究使用過了一遍,並且儘可能在項目中都有使用,讓本身有深一點的體會
並且我對着官方文檔,一個個作了詳細的筆記,並且聯想過了使用場景。閉包

二、JavaScript 紮實基礎
幸虧本身以前花了大力氣去給本身打基礎,讓本身如今的 JavaScript 基礎還算不錯。
逼着本身把不少本 JavaScript 書都看完了,而且作了詳細筆記。像是【 JavaScript易維護】【JavaScript性能 】,【JavaScript 高級程序設計】【巴菲特給股東的信】看了兩遍,說不上精通,也算是還能夠?app

三、看完 JavaScript 設計模式
光是 JavaScript 設計模式 這本書 我就看了一年半,不能說本身把全部設計模式都掌握了,掌握了大部分吧,設計模式港真真的頗有趣,否則我也不會決心學
在這裏推薦 張容銘的 【JavaScript設計模式】,書講得很是透徹和詳細,我是從徹底不懂開始看的
也常用一部分,我一直以設計模式爲個人項目基構。就是 能用設計模式的地方,我都儘可能使用設計模式。
設計模式看起來就像是 劍客 的劍譜,有招有式,連人家武俠劇發功的時候都知道 喊出 招式的名字... 降龍十八掌!!!!
野路子難登大雅之堂,主要是很差看啊,代碼爲了好維護,易擴展框架

四、學會調試
我很大膽地說,若是你不會調試,你看 Vue 源碼,或者你會想死,你會出現這個場景...
MMP,這個方法是怎麼跳到 那個方法的,那個方法和 這個方法又是怎麼聯繫起來的?
也許你能夠慢慢 使用 函數名字 去尋找,可是無疑你會多消耗幾倍時間,並且你會更煩
使用調試真的方便,之前我也真的不喜歡調試,以爲好像很難???
更喜歡使用 console.log 去打印信息.....
是啊,我本身寫項目的時候,我仍是會使用 console.log 去調試.......
那是由於我本身代碼,我知道怎麼跑,你 看別人的代碼,仍是超級抽象的框架,使用 console.log 的方式.....
放心,相信我,你會掉不少頭髮.........
這裏,我使用的是 VSCode 去調試,真的簡單又方便,我當時也真的很難去讓本身又要學一個東西
可是我咬咬牙,我仍是學了,感謝本身......
我能夠保證,你從不懂到掌握,只要不到十分鐘,簡直就是 現實版的 十分鐘精通到入門
好吧,下面開始說,Vue 的簡單總結。dom


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());
       }
    }
}
....

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

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
}

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

就我看到的設計模式就有
觀察者模式、狀態模式、節流模式、 參與者模式、備忘錄模式、單例模式 裝飾者模式、組合繼承模式、鏈模式.........
我懷疑 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// 是不是註釋節點
isClone:// 是不是克隆節點
isOnce// 是否有v-once 指令(若是有當前指令,會跳過編譯)
_isComponent// 是不是組件

多用標誌位,控制流程,替代多餘的判斷(直接判斷標誌位來確認身份,不用作太多的判斷),減小開銷
上面那些變量,你們沒看源碼,可能有些懵逼,不要緊,就當先知道有這個東西就行了


Vue 源碼分幾步走

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

Vue 的主體內容

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

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

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

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

v2-b5b7d1e5889a1ab479f46caf52a28d8e_b.jpg

相關文章
相關標籤/搜索