原文:http://www.javashuo.com/article/p-yyifgmpb-co.htmlhtml
MVVM 是Model-View-ViewModel 的縮寫,它是一種基於前端開發的架構模式,其核心是提供對View 和 ViewModel 的雙向數據綁定,這使得ViewModel 的狀態改變能夠自動傳遞給 View,即所謂的數據雙向綁定。前端
Vue.js 是一個提供了 MVVM 風格的雙向數據綁定的 Javascript 庫,專一於View 層。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel負責鏈接 View 和 Model,保證視圖和數據的一致性,這種輕量級的架構讓前端開發更加高效、便捷。 jquery
MVC 即 Model-View-Controller 的縮寫,就是 模型-視圖-控制器 , 也就是說一個標準的Web 應用程序是由這三部分組成的: 後端
View 用來把數據以某種方式呈現給用戶。
Model 其實就是數據。
Controller 接收並處理來自用戶的請求,並將 Model 返回給用戶。
在HTML5 還未火起來的那些年,MVC 做爲Web 應用的最佳實踐是OK 的,這是由於 Web 應用的View 層相對來講比較簡單,前端所須要的數據在後端基本上均可以處理好,View 層主要是作一下展現,那時候提倡的是 Controller 來處理複雜的業務邏輯,因此View 層相對來講比較輕量,就是所謂的瘦客戶端思想。數組
2010年到2011年,HTML5概念被熱炒,受到追捧,2012年,W3C 正式宣佈HTML5規範已經正式定稿。2013年我剛進公司就接觸了第一個 HTML5 框架 Sench touch, 它是一款用來構建移動應用的HTML5 框架,它將先後端完全分離,前端採用MVC 架構,做爲一個獨立的項目工程來維護。架構
相對 HTML4 , HTML5 最大的亮點是它爲移動設備提供了一些很是有用的功能,使得 HTML5 具有了開發App的能力, HTML5開發App 最大的好處就是跨平臺、快速迭代和上線,節省人力成本和提升效率,所以不少企業開始對傳統的App進行改造,逐漸用H5代替Native,到2015年的時候,市面上大多數App 或多或少嵌入都了H5 的頁面。框架
既然要用H5 來構建 App, 那View 層所作的事,就不只僅是簡單的數據展現了,它不只要管理複雜的數據狀態,還要處理移動設備上各類操做行爲等等。所以,前端也須要工程化,也須要一個相似於MVC 的框架來管理這些複雜的邏輯,使開發更加高效。 但這裏的 MVC 又稍微發了點變化:函數
View UI佈局,展現數據。
Model 管理數據。
Controller 響應用戶操做,並將 Model 更新到 View 上。
這種 MVC 架構模式對於簡單的應用來看起是OK 的,也符合軟件架構的分層思想。 但實際上,隨着H5 的不斷髮展,人們更但願使用H5 開發的應用能和Native 媲美,或者接近於原生App 的體驗效果,因而前端應用的複雜程度已不一樣往日,今非昔比。這時前端開發就暴露出了三個痛點問題:佈局
其實,早期jquery 的出現就是爲了前端能更簡潔的操做DOM 而設計的,但它只解決了第一個問題,另外兩個問題始終伴隨着前端一直存在。性能
MVVM 由 Model,View,ViewModel 三部分構成,Model 層表明數據模型,也能夠在Model中定義數據修改和操做的業務邏輯;View 表明UI 組件,它負責將數據模型轉化成UI 展示出來,ViewModel 是一個同步View 和 Model的對象。
在MVVM架構下,View 和 Model 之間並無直接的聯繫,而是經過ViewModel進行交互,Model 和 ViewModel 之間的交互是雙向的, 所以View 數據的變化會同步到Model中,而Model 數據的變化也會當即反應到View 上。
ViewModel 經過雙向數據綁定把 View 層和 Model 層鏈接了起來,而View 和 Model 之間的同步工做徹底是自動的,無需人爲干涉,所以開發者只需關注業務邏輯,不須要手動操做DOM, 不須要關注數據狀態的同步問題,複雜的數據狀態維護徹底由 MVVM 來統一管理。
Vue.js 是採用 Object.defineProperty 的 getter 和 setter,並結合觀察者模式來實現數據綁定的。當把一個普通 Javascript 對象傳給 Vue 實例來做爲它的 data 選項時,Vue 將遍歷它的屬性,用 Object.defineProperty 將它們轉爲 getter/setter。用戶看不到 getter/setter,可是在內部它們讓 Vue 追蹤依賴,在屬性被訪問和修改時通知變化。
Observer 數據監聽器,可以對數據對象的全部屬性進行監聽,若有變更可拿到最新值並通知訂閱者,內部採用Object.defineProperty的getter和setter來實現。
Compile 指令解析器,它的做用對每一個元素節點的指令進行掃描和解析,根據指令模板替換數據,以及綁定相應的更新函數。
Watcher 訂閱者, 做爲鏈接 Observer 和 Compile 的橋樑,可以訂閱並收到每一個屬性變更的通知,執行指令綁定的相應回調函數。
Dep 消息訂閱器,內部維護了一個數組,用來收集訂閱者(Watcher),數據變更觸發notify 函數,再調用訂閱者的 update 方法。
從圖中能夠看出,當執行 new Vue() 時,Vue 就進入了初始化階段,一方面Vue 會遍歷 data 選項中的屬性,並用 Object.defineProperty 將它們轉爲 getter/setter,實現數據變化監聽功能;另外一方面,Vue 的指令編譯器Compile 對元素節點的指令進行掃描和解析,初始化視圖,並訂閱Watcher 來更新視圖, 此時Wather 會將本身添加到消息訂閱器中(Dep),初始化完畢。
當數據發生變化時,Observer 中的 setter 方法被觸發,setter 會當即調用Dep.notify(),Dep 開始遍歷全部的訂閱者,並調用訂閱者的 update 方法,訂閱者收到通知後對視圖進行相應的更新。