淺析 web 前端 MVVM

前言

記得四個月前有一次面試,面試官問我 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 基本信息

MVVM 是一種架構模式,也被稱爲 model-view-binder。它由微軟架構師 Ken Cooper 和 Ted Peters 開發,經過利用 WPF(微軟 .NET 圖形系統)和 Silverlight(WPF 的互聯網應用派生品)的特性來簡化用戶界面的事件驅動程序設計。微軟的 WPF 和 Silverlight 架構師之一John Gossman 於 2005 年在他的博客上發表了 MVVM。ajax

MVVM 結構初見

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 爲中心理解。

MVVM 與 MVC 的對比

認真看過 Vue 文檔大概都能注意到,Vue 實例的變量名是 vm,文檔中還很嚴謹地補充了一句 「雖然沒有徹底遵循 MVVM 模型,可是 Vue 的設計也受到了它的啓發」。

按照上面不一樣的工程師眼裏有不一樣的 MVC 結構的引言,Vue 雖然「沒有徹底遵循 MVVM 模型」,可是我以爲這就是一種 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

與之對比,MVC 的狀況:

View:同樣是展示給用戶的部分,整個或部分 HTML 頁面。

Model:JavaScript 的變量數據(能夠包含 ajax 獲取數據的邏輯,或是一個數據管理機制),可是在這裏要額外地添加提醒 View 更新的機制。幾個月前我還迷糊爲何 MVC 也有觀察者模式,MVC 的觀察者是 View,在 Model 註冊爲觀察者就能在 Model 更新時更新。

Controller:用戶操做邏輯放置點,輸入是用戶的操做,輸出是對 Model 的修改。

那麼問題來了:MVC 和 MVVM 都用了觀察者模式,二者有何不一樣?

mvc & mvp

看圖說話:

在理解 MVVM 和 MVC 的區別時我糾結了好久,基於 Vue 來講,感受很是像 MVC:頁面訂閱數據;數據更新時頁面更新,可是看了這幅圖後豁然開朗。

圖中對比的是 MVC 和 MVP,可是 MVP 和 MVVM 的區別基本就是 MVVM 把三者間的操做自動綁定了,不用開發者操心 V 和 P 之間的相互操做。

MVC 是由 M 通知 V,但 MVVM 是 M 通知 VM(M 和 V 沒有直接關係)。

拓展:React 只是 MVC 的 V?

至今還普遍流傳這這麼一句話:React不是一個MVC框架,而是一個用於構建組件化UI的庫,是一個前端界面開發工具。

這不是錯的,但確定是過期的。在 React 剛面世的時候,開發團隊強調了這種新型的界面便攜方法(Jsx 使用函數生成界面),強調 Virtual DOM 和 diff 算法,然後來,官網已經把相關描述修改了。

如今的 react 不僅是 mvc 的 m

理解、交流

進步不能缺乏交流,若是你們對三種架構模式的區別有不一樣看法,請必定要在評論區留言。文中若出現錯誤觀點也請提醒,謝謝熱愛編程的你們。

參考文獻

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/

相關文章
相關標籤/搜索