對于vue.js的動態(tài)數據綁定,經過反復地看源碼和博客講解,總算能夠理解它的實現了,心累~ 分享一下學習成果,同時也算是做個記錄。完整代碼GitHub地址:https://github.com/hanrenguang/Dynamic-data-binding。也可以到倉庫的 README 閱讀本文,容我厚臉皮地求 star,求 follow。
整體思路
不知道有沒有同學和我一樣,看著vue的源碼卻不知從何開始,真叫人頭大。硬生生地看了observer, watcher, compile這幾部分的源碼,只覺得一臉懵逼。最終,從這里得到啟發(fā),作者寫得很好,值得一讀。
關于動態(tài)數據綁定呢,需要搞定的是 Dep , Observer , Watcher , Compile 這幾個類,他們之間有著各種聯系,想要搞懂源碼,就得先了解他們之間的聯系。下面來理一理:
Observer 所做的就是劫持監(jiān)聽所有屬性,當有變動時通知 Dep Watcher 向 Dep 添加訂閱,同時,屬性有變化時,Observer 通知 Dep,Dep 則通知 Watcher Watcher 得到通知后,調用回調函數更新視圖 Compile 則是解析所綁定元素的 DOM 結構,對所有需要綁定的屬性添加 Watcher 訂閱由此可以看出,當屬性發(fā)生變化時,是由Observer -> Dep -> Watcher -> update view,Compile 在最開始解析 DOM 并添加 Watcher 訂閱后就功成身退了。
從程序執(zhí)行的順序來看的話,即 new Vue({}) 之后,應該是這樣的:先通過 Observer 劫持所有屬性,然后 Compile 解析 DOM 結構,并添加 Watcher 訂閱,再之后就是屬性變化 -> Observer -> Dep -> Watcher -> update view,接下來就說說具體的實現。
從new一個實例開始談起
網上的很多源碼解讀都是從 Observer 開始的,而我會從 new 一個MVVM實例開始,按照程序執(zhí)行順序去解釋或許更容易理解。先來看一個簡單的例子:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>test</title></head><body> <div class="test"> <p>{{user.name}}</p> <p>{{user.age}}</p> </div> <script type="text/javascript" src="hue.js"></script> <script type="text/javascript"> let vm = new Hue({ el: '.test', data: { user: { name: 'Jack', age: '18' } } }); </script></body></html>接下來都將以其為例來分析。下面來看一個簡略的 MVVM 的實現,在此將其命名為 hue。為了方便起見,為 data 屬性設置了一個代理,通過 vm._data 來訪問 data 的屬性顯得麻煩且冗余,通過代理,可以很好地解決這個問題,在注釋中也有說明。添加完屬性代理后,調用了一個 observe 函數,這一步做的就是 Observer 的屬性劫持了,這一步具體怎么實現,暫時先不展開。先記住他為 data 的屬性添加了 getter 和 setter。
新聞熱點
疑難解答
圖片精選