記得四個月前有一次面試,面試官問我 MVVM 是什麼,MVVM 的本質是什麼。我大腦一片混亂,那時我對 MVVM 的認知就只是「雙向綁定「和「Vue」,以這個關鍵字簡單回答了幾句,我反問 MVVM 的本質是什麼,對方就重複一次雙向綁定。我怎麼以爲對方也沒懂就隨便這麼一問呢...javascript
其實面試完我就急着探求 MVVM 的真諦,查了資料,作了筆記,如下是我四個月前的理解:前端
ViewModel 和 View 是互相綁定的,咱們不直對界面進行操做,只須要修改數據。而和 MVC 的區別是:MVC 的 C,接收了數據,須要手動經過 js 修改 dom,這包含了對 V 的操做而不管是 vue 仍是 react,都不須要對 dom 進行操做,view 和 viewmodel 的聯繫顯然比 mvc 裏 vc 的聯繫緊密多了,這就是咱們常說的雙向綁定。我以爲是否是沒有必要把 MV* 搞得這麼清楚?只要知道 MVVM 的本質是雙向數據綁定就行了?vue
四個月前的我投降了,爲了應付面試我依然只記得雙向綁定,並且 MVC 和 MVVM 的概念依然不清晰,本質的區別仍是沒搞懂。java
不過不清晰真的很正常。react
由於網上關於 mvvm 和其餘 mv* 結構的文章很多,按道理應該不難理解,可是不少文章對 mv* 的描述都不一致,這就致使不少原本就懵逼的小白更加混亂(沒錯就是我)。web
If you put ten software architects into a room and have them discuss what the Model-View-Controller pattern is, you will end up with twelve different opinions. --Josh Smith面試
MVVM 是一種架構模式,也被稱爲 model-view-binder。它由微軟架構師 Ken Cooper 和 Ted Peters 開發,經過利用 WPF(微軟 .NET 圖形系統)和 Silverlight(WPF 的互聯網應用派生品)的特性來簡化用戶界面的事件驅動程序設計。微軟的 WPF 和 Silverlight 架構師之一John Gossman 於 2005 年在他的博客上發表了 MVVM。ajax
MVVM 與其餘兩種架構的對比:算法
MVVM:VM 在 UI 層之下。VM 爲 view 暴露數據和方法,VM 推送數據到在它之下的 model。編程
MVC:view 層在結構頂層,controller 在 view 之下。model 在 controller 之下。view 指向 controller,controller 指向 model。model 更改時 view 會獲得提醒(這個狀況是一個單向流)。
MVP:controller 替換爲 presenter。presenter 與 view 分庭抗禮。presenter 監聽 view 和 model 的事件,做爲中間人在他們之間調解兩邊的事件,輔助兩邊交流。
MVVM 對於 MVC 來講更容易理解,由於 MVC 通過長久的實踐,產生了不少框架,這些框架的適用領域也各有不一樣:有後端渲染工程、原生應用工程、先後端分離後的前端工程等,在實現 MVC 模式時理所固然地會有必定區別,這就致使了 MVC 的多樣性。因此對於不一樣的狀況,對 MVC 的理解不是徹底同樣的。一樣的狀況 MVVM 也有,做爲一個較新的模式,實現比 MVC 少。此文介紹的 MVVM 模式主要以 Vue 爲中心理解。
認真看過 Vue 文檔大概都能注意到,Vue 實例的變量名是 vm,文檔中還很嚴謹地補充了一句 「雖然沒有徹底遵循 MVVM 模型,可是 Vue 的設計也受到了它的啓發」。
按照上面不一樣的工程師眼裏有不一樣的 MVC 結構的引言,Vue 雖然「沒有徹底遵循 MVVM 模型」,可是我以爲這就是一種 Vue 特化的 MVVM。
View:單文件裏 <template>
標籤的內容,展示給用戶的內容,與 ViewModel 雙向綁定,能夠在其中插入 ViewModel 提供的數據。
ViewModel:Vue 實例整個都是 ViewModel,與 View 雙向綁定,用戶在 View 修改數據或發出 ajax 等指令時, ViewModel 會及時相應,接着向下修改 Model——至此能夠看出 Model 和 View 是沒有直接關係的。
Model:這一層或者有歧義。爲了更好理解 Model 須要引入 Vuex,在有 Vuex 的狀況下,Vuex 提供的數據就是 Model,這符合後端架構中 Model 包含業務邏輯的狀況。可是在無 Vuex 的狀況下,Model 應該就是 Vue 實例的 data 屬性,也就是 JavaScript 數據對象自己。
與之對比,MVC 的狀況:
View:同樣是展示給用戶的部分,整個或部分 HTML 頁面。
Model:JavaScript 的變量數據(能夠包含 ajax 獲取數據的邏輯,或是一個數據管理機制),可是在這裏要額外地添加提醒 View 更新的機制。幾個月前我還迷糊爲何 MVC 也有觀察者模式,MVC 的觀察者是 View,在 Model 註冊爲觀察者就能在 Model 更新時更新。
Controller:用戶操做邏輯放置點,輸入是用戶的操做,輸出是對 Model 的修改。
那麼問題來了:MVC 和 MVVM 都用了觀察者模式,二者有何不一樣?
看圖說話:
在理解 MVVM 和 MVC 的區別時我糾結了好久,基於 Vue 來講,感受很是像 MVC:頁面訂閱數據;數據更新時頁面更新,可是看了這幅圖後豁然開朗。
圖中對比的是 MVC 和 MVP,可是 MVP 和 MVVM 的區別基本就是 MVVM 把三者間的操做自動綁定了,不用開發者操心 V 和 P 之間的相互操做。
MVC 是由 M 通知 V,但 MVVM 是 M 通知 VM(M 和 V 沒有直接關係)。
至今還普遍流傳這這麼一句話:React不是一個MVC框架,而是一個用於構建組件化UI的庫,是一個前端界面開發工具。
這不是錯的,但確定是過期的。在 React 剛面世的時候,開發團隊強調了這種新型的界面便攜方法(Jsx 使用函數生成界面),強調 Virtual DOM 和 diff 算法,然後來,官網已經把相關描述修改了。
進步不能缺乏交流,若是你們對三種架構模式的區別有不一樣看法,請必定要在評論區留言。文中若出現錯誤觀點也請提醒,謝謝熱愛編程的你們。
參考文獻
https://zh.wikipedia.org/wiki/MVVM
https://russelleast.wordpress.com/2008/08/09/overview-of-the-modelview-viewmodel-mvvm-pattern-and-data-binding/
https://medium.com/javascript-inside/what-if-react-was-really-only-the-v-in-mvc-5854fd6f601c
https://web.archive.org/web/20150219153055/http://joel.inpointform.net/software-development/mvvm-vs-mvp-vs-mvc-the-differences-explained/