【Vue原理】調試Vue源碼

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

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

【Vue原理】響應式原理 - 白話版學習

本文打算 白話文的形式講解 Vue 的響應式系統原理,儘可能不涉及源碼。code

只闡述工做流程,不想內容過多過於繁雜,致使你們會沒有什麼閱讀的興趣。對象

因此我從此打算把每個內容分紅 白話版和 源碼版。blog

白話版,就是讓你們不用花費太多腦力,不用消耗太多時間,就能輕鬆地看完並大體瞭解內容。圖片

有時間精力的人能夠閱讀源碼版 ,而後本身參考源碼,來進行研究學習。有什麼錯誤的地方,感謝你們可以指出get


<br> <br>源碼

響應式系統

咱們都知道,只要在 Vue 實例中聲明過的數據,那麼這個數據就是響應式的。工作流

什麼是響應式,也便是說,數據發生改變的時候,視圖會從新渲染,匹配更新爲最新的值。

也正是由於這個系統,讓咱們能夠脫離界面的束縛,只須要操做數據。

咱們能夠問出下面三個問題

一、Vue 是怎麼知道數據改變?

二、Vue 在數據改變時,怎麼知道通知哪些視圖更新?

三、Vue 在數據改變時,視圖怎麼知道何時更新?

問題的謎底將在下面一一解開

如今,我將會講解三個重要的概念

Object.defineProperty,依賴收集,依賴更新

<br> <br>

Object.defineProperty

這個方法,是 Vue 響應式系統的精髓,骨髓,腦髓

使用 Object.defineProperty 能夠爲對象中的每個屬性,設置 get 和 set 方法

Object.defineProperty 能夠爲屬性設置不少特性,例如 configurable,enumerable,可是如今不過多解釋,重點只放在 get 和 set

<br>

那麼 get 和 set 方法有什麼用?

get 值是一個函數,當屬性被訪問時,會觸發 get 函數

set 值一樣是一個函數,當屬性被賦值時,會觸發 set 函數

<br>

舉個例子
var obj={    
    name:"神仙朱"
}
Object.defineProperty(obj,"name",{
    get(){        
        console.log("get 被觸發")
    },
    set(val){        
        console.log("set 被觸發")
    }
})

當我訪問 obj.name 時,會打印 ' get 被觸發 '

當我爲 obj.name 賦值時,obj.name = 5,會打印 ' set 被觸發 '

這即可以回答了我開篇的第一個問題

Vue 是怎麼知道數據改變的呢?

恩,Vue 在 屬性的 set 方法中作了手腳,於是當數據改變時,觸發 屬性的 set 方法,Vue 就能知道數據有改變


<br> <br>

依賴收集

<br>

簡單地說

data 中的聲明的每一個屬性,都擁有一個數組,保存着 誰依賴(使用)了 它

<br>

舉個例子
new Vue({    
    data(){        
        return {            
            name:"神仙朱"        
        }    
    }
})

而後 頁面A 引用了name

<div>{{name}}</div>

此時,name 把 頁面 A 存在它的後宮中(這個頁面依賴我)

<br>

爲何呢?

由於它知道誰依賴它以後,它就能夠在發生改變的時候,通知 依賴它的頁面,從而讓頁面完成更新

<br>

TIP

實際上,會依賴 name 的地方,不僅是頁面,還會有 computed,watch.... 等等,可是這裏咱們所有使用頁面一詞替代

這就是依賴收集,把 依賴了我(使用了個人東西),通通保存起來。

但是,保存在哪裏,具體保存的是什麼東西,咱們這裏暫時不深刻,由於這是白話文。

我按上面的例子,從Vue 內部打印一份數據供你們簡單瞭解便可

在這裏插入圖片描述 能夠看到,name 屬性,使用了 一個 dep 保存了 頁面A 這個依賴,而保存的其實是 頁面A的 Watcher。

<br>

TIP

簡單說一下,watcher 是什麼,每一個 Vue 實例都會擁有一個專屬的 watcher,可用於實例更新

<br>

總結一下

一、data 中每一個聲明的屬性,都會有一個 專屬的依賴收集器 subs

二、當頁面使用到 某個屬性時,頁面的 watcher 就會被 放到 依賴收集器 subs 中

數據 是在何時進行 收集依賴 的呢?

答案是,ObjectdefineProperty - get

當 頁面 A 讀取了 name 時,會觸發 name 的 get 函數,此時,name 就會保存 頁面A 的 watcher 啦!

這即可以回答了我開篇的第二個問題

Vue 在數據改變時,怎麼知道通知哪些視圖更新?

恩,通知那些存在 依賴收集器中的 視圖


<br> <br>

依賴更新

依賴更新,就是,通知全部的依賴進行更新

通過上面的講解,咱們都知道,每一個屬性都會保存有一個 依賴收集器 subs

而這個 依賴收集器,是用來在 數據變化時,通知更新的

數據 是在 何時進行 依賴更新 的呢?

答案是,Object.defineProperty - set

<br>

以上面的 Vue 實例 爲例

當 name 改變的時候,name 會遍歷本身的 依賴收集器 subs,逐個通知 watcher,讓 watcher 完成更新

這裏 name 會通知 頁面A,頁面A 從新讀取新的 name ,而後完成渲染

<br>

這即可以回答了我開篇的第二個問題

Vue 在數據改變時,視圖怎麼知道何時更新?

恩,在數據變化觸發 set 函數時,通知視圖,視圖開始更新

<br>

簡單總結

一、Object.defineProperty - get ,用於 依賴收集

二、Object.defineProperty - set,用於 依賴更新

三、每一個 data 聲明的屬性,都擁有一個的專屬依賴收集器 subs

四、依賴收集器 subs 保存的依賴是 watcher

五、watcher 可用於 進行視圖更新


<br> <br>

最後

哈哈,最近好多的人都說我很高產,其實個人文章就是個人筆記,我作了不少筆記,可是個人筆記樣式不堪入目,因此發文章須要排版,並且部份內容須要寫得更加詳細一些,所以須要更多的時間去驗證研究,因此有時懶得發文章。

謝謝個人每個粉絲的支持,我一直之內容高質量,排版看得舒服 爲目標,對待每一篇文章,因此很是耗時,可是我很認真。

若是發現有錯誤,說得不對的地方,很是感謝可以指出,本人會有重謝哈哈哈,很是歡迎一塊兒探討學習

公衆號

相關文章
相關標籤/搜索