Vue是一個響應式的框架,響應式是指:數據模型僅僅是普通的 JavaScript 對象。而當你修改它們時,視圖會進行更新。數組
那麼Vue是怎麼作到響應式的呢?框架
能夠從兩個方面來討論:Object和Array。函數
受現代JavaScript 的限制 (以及廢棄 Object.observe),Vue不能檢測到對象屬性的添加或刪除。因此Vue經過Object.defineProperty來處理數據,把屬性變成getter/setter屬性,由於Object.defineProperty是ES5的一個不能shim的特性,因此不支持IE8及如下。server
Vue追蹤變化,是把對象用Object.defineProperty把遍歷對象,使用Observer類把對象的每一個屬性改寫成用getter/setter來設置和獲取值的改變。這樣Vue就能夠經過觸發getter和setter方法來處理數據,就能夠獲取數據的改變。對象
2.1 什麼是依賴?ip
用到該屬性的地方,就是依賴,可是Vue封裝了一個watch類來看成依賴,這個watch類能通知使用該屬性的全部依賴。因此Vue收集的依賴就是收集watch類。get
2.2 如何收集依賴?原型
Vue在getter方法裏收集依賴,Vue把依賴解耦成一個專門的Dep類,來處理收集和觸發依賴。在使用該數據的時候,便把依賴收集到Dep裏。io
2.3 如何觸發依賴class
在數據發生改變的setter函數裏觸發依賴,Vue聲明的watch類,當數據發生了改變的時候,Vue通知watch數據發生變化,讓watch本身去通知依賴發生改變。
Vue使用Object.defineProperty的getter和setter來把對象變成響應式的對象,可是也由於這個,Vue能監聽到該Object屬性值的變化,卻監聽不到Object增長和刪除屬性。因此Vue提供了兩個API:vm.delete來處理增長屬性和刪除屬性。
Vue對象是經過getter/setter 來監聽到對象的數據變化從而讓對象變成響應式的。可是在數組裏,有一些原型上的方法好比push,pop,shift…等,並不會觸發getter/setter 就能夠改變數組的值,Vue在這個時候,就沒有辦法進行監遵從而觸發視圖的改變了。
Vue重寫了push,pop,shift,unshift,reverse,sort,splice這7個會改變Array自己的原型方法,並經過一個攔截器,把須要響應的數組,覆蓋他們的原型方法。value.proto=arraysMethods.若是不支持__proto__的屬性,那麼Vue會暴力的把這些方法放到這些數組自己。
2.1 在哪兒收集和觸發依賴
Vue對數組和對象都同樣,都是在getter裏收集依賴,在setter裏觸發依賴。
2.2 依賴放在哪兒
對象的依賴放在Dep類裏,而數組的依賴放在Observer實例的Dep裏。目的是爲了在getter和Array的攔截器都裏能訪問到Observer的實例。
Vue改寫了上面Object的Observer的類,給每一個屬性加一個__ob__屬性,經過對該屬性的來判斷是否響應式,且是否發生改變,從而觸發依賴。