以前對 MVVM 模式一直只是模模糊糊的認識,正所謂沒有實踐就沒有發言權,經過這兩年對 Vue 框架的深刻學習和項目實踐,終於能夠裝B了有了撥開雲霧見月明的感受。html
Model–View–ViewModel(MVVM) 是一個軟件架構設計模式,由微軟 WPF 和 Silverlight 的架構師 Ken Cooper 和 Ted Peters 開發,是一種簡化用戶界面的事件驅動編程方式。由 John Gossman(一樣也是 WPF 和 Silverlight 的架構師)於2005年在他的博客上發表。前端
MVVM 源自於經典的 Model–View–Controller(MVC)模式(期間還演化出了 Model-View-Presenter(MVP)模式,可忽略不計)。MVVM 的出現促進了 GUI 前端開發與後端業務邏輯的分離,極大地提升了前端開發效率。MVVM 的核心是 ViewModel 層,它就像是一箇中轉站(value converter),負責轉換 Model 中的數據對象來讓數據變得更容易管理和使用,該層向上與視圖層進行雙向數據綁定,向下與 Model 層經過接口請求進行數據交互,起呈上啓下做用。以下圖所示:ajax
MVVM模式數據庫
MVVM 已經至關成熟了,主要運用但不只僅在網絡應用程序開發中。KnockoutJS 是最先實現 MVVM 模式的前端框架之一,當下流行的 MVVM 框架有 Vue,Angular 等。編程
簡單畫了一張圖來講明 MVVM 的各個組成部分:json
MVVM分層示意圖後端
分層設計一直是軟件架構的主流設計思想之一,MVVM 也不例外。設計模式
View 是視圖層,也就是用戶界面。前端主要由 HTML 和 CSS 來構建,爲了更方便地展示 ViewModel 或者 Model 層的數據,已經產生了各類各樣的先後端模板語言,好比 FreeMarker、Marko、Pug、Jinja2等等,各大 MVVM 框架如 KnockoutJS,Vue,Angular 等也都有本身用來構建用戶界面的內置模板語言。api
Model 是指數據模型,泛指後端進行的各類業務邏輯處理和數據操控,主要圍繞數據庫系統展開。後端的處理一般會很是複雜:前端框架
先後端對比
後端:咱們這裏的業務邏輯和數據處理會很是複雜!
前端:關我屁事!
後端業務處理再複雜跟咱們前端也沒有半毛錢關係,只要後端保證對外接口足夠簡單就好了,我請求api,你把數據返出來,咱倆就這點關係,其餘都扯淡。
ViewModel 是由前端開發人員組織生成和維護的視圖數據層。在這一層,前端開發者對從後端獲取的 Model 數據進行轉換處理,作二次封裝,以生成符合 View 層使用預期的視圖數據模型。須要注意的是 ViewModel 所封裝出來的數據模型包括視圖的狀態和行爲兩部分,而 Model 層的數據模型是隻包含狀態的,好比頁面的這一塊展現什麼,那一塊展現什麼這些都屬於視圖狀態(展現),而頁面加載進來時發生什麼,點擊這一塊發生什麼,這一塊滾動時發生什麼這些都屬於視圖行爲(交互),視圖狀態和行爲都封裝在了 ViewModel 裏。這樣的封裝使得 ViewModel 能夠完整地去描述 View 層。因爲實現了雙向綁定,ViewModel 的內容會實時展示在 View 層,這是激動人心的,由於前端開發者不再必低效又麻煩地經過操縱 DOM 去更新視圖,MVVM 框架已經把最髒最累的一塊作好了,咱們開發者只須要處理和維護 ViewModel,更新數據視圖就會自動獲得相應更新,真正實現數據驅動開發。看到了吧,View 層展示的不是 Model 層的數據,而是 ViewModel 的數據,由 ViewModel 負責與 Model 層交互,這就徹底解耦了 View 層和 Model 層,這個解耦是相當重要的,它是先後端分離方案實施的重要一環。
扯了這麼多,並無什麼卵用。千言萬語不如一個栗子來的乾脆,下面用一個 Vue 實例來講明 MVVM 的具體表現。
Vue 的 View 模板:
<div id="app"> <p>{{message}}</p> <button v-on:click="showMessage()">Click me</button> </div>
Vue 的 ViewModel 層(下面是僞代碼):
var app = new Vue({ el: '#app', data: { // 用於描述視圖狀態(有基於 Model 層數據定義的,也有純前端定義) message: 'Hello Vue!', // 純前端定義 server: {}, // 存放基於 Model 層數據的二次封裝數據 }, methods: { // 用於描述視圖行爲(徹底前端定義) showMessage(){ let vm = this; alert(vm.message); } }, created(){ let vm = this; // Ajax 獲取 Model 層的數據 ajax({ url: '/your/server/data/api', success(res){ // TODO 對獲取到的 Model 數據進行轉換處理,作二次封裝 vm.server = res; } }); } })
服務端的 Model 層(省略業務邏輯處理,只描述對外接口):
{ "url": "/your/server/data/api", "res": { "success": true, "name": "IoveC", "domain": "www.cnblogs.com" } }
這就是完整的 MVVM 編程模式。
代碼執行以後雙向綁定的效果以下:
Vue實現的響應的數據綁定
嘿嘿,先後端能夠成功分手了,之後不再用關心後端個錘子開發進度\暴怒臉,複雜實現,blabla...,盡情享用前端如絲般順滑的開發快感吧:)
臨末,送你們一個福利 😘