寫文章不容易,點個讚唄兄弟 專一 Vue 源碼分享,文章分爲白話版和 源碼版,白話版助於理解工做原理,源碼版助於瞭解內部詳情,讓咱們一塊兒學習吧 研究基於 Vue版本 【2.5.17】數組
若是你以爲排版難看,請點擊 下面連接 或者 拉到 下面關注公衆號也能夠吧函數
本文打算 白話文的形式講解 Vue 的響應式系統原理,儘可能不涉及源碼。code
只闡述工做流程,不想內容過多過於繁雜,致使你們會沒有什麼閱讀的興趣。對象
因此我從此打算把每個內容分紅 白話版和 源碼版。blog
白話版,就是讓你們不用花費太多腦力,不用消耗太多時間,就能輕鬆地看完並大體瞭解內容。圖片
有時間精力的人能夠閱讀源碼版 ,而後本身參考源碼,來進行研究學習。有什麼錯誤的地方,感謝你們可以指出get
<br> <br>源碼
咱們都知道,只要在 Vue 實例中聲明過的數據,那麼這個數據就是響應式的。工作流
什麼是響應式,也便是說,數據發生改變的時候,視圖會從新渲染,匹配更新爲最新的值。
也正是由於這個系統,讓咱們能夠脫離界面的束縛,只須要操做數據。
咱們能夠問出下面三個問題
一、Vue 是怎麼知道數據改變?
二、Vue 在數據改變時,怎麼知道通知哪些視圖更新?
三、Vue 在數據改變時,視圖怎麼知道何時更新?
問題的謎底將在下面一一解開
如今,我將會講解三個重要的概念
Object.defineProperty,依賴收集,依賴更新
<br> <br>
這個方法,是 Vue 響應式系統的精髓,骨髓,腦髓
使用 Object.defineProperty 能夠爲對象中的每個屬性,設置 get 和 set 方法
Object.defineProperty 能夠爲屬性設置不少特性,例如 configurable,enumerable,可是如今不過多解釋,重點只放在 get 和 set
<br>
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>
實際上,會依賴 name 的地方,不僅是頁面,還會有 computed,watch.... 等等,可是這裏咱們所有使用頁面一詞替代
這就是依賴收集,把 依賴了我(使用了個人東西),通通保存起來。
但是,保存在哪裏,具體保存的是什麼東西,咱們這裏暫時不深刻,由於這是白話文。
我按上面的例子,從Vue 內部打印一份數據供你們簡單瞭解便可
能夠看到,name 屬性,使用了 一個 dep 保存了 頁面A 這個依賴,而保存的其實是 頁面A的 Watcher。
<br>
簡單說一下,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>
當 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>
哈哈,最近好多的人都說我很高產,其實個人文章就是個人筆記,我作了不少筆記,可是個人筆記樣式不堪入目,因此發文章須要排版,並且部份內容須要寫得更加詳細一些,所以須要更多的時間去驗證研究,因此有時懶得發文章。
謝謝個人每個粉絲的支持,我一直之內容高質量,排版看得舒服 爲目標,對待每一篇文章,因此很是耗時,可是我很認真。
若是發現有錯誤,說得不對的地方,很是感謝可以指出,本人會有重謝哈哈哈,很是歡迎一塊兒探討學習