MVVM框架
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 層通過介面請求進行資料互動,起呈上啟下作用。如下圖所示:
MVVM 已經相當成熟了,主要運用但不僅僅在網路應用程式開發中。KnockoutJS 是最早實現 MVVM 模式的前端框架之一,當下流行的 MVVM 框架有 Vue,Angular 等。
組成部分
簡單畫了一張圖來說明 MVVM 的各個組成部分:
分層設計一直是軟體架構的主流設計思想之一,MVVM 也不例外。
# View 層
View 是檢視層,也就是使用者介面。前端主要由 HTML 和 CSS 來構建,為了更方便地展現 ViewModel 或者 Model 層的資料,已經產生了各種各樣的前後端模板語言,比如 FreeMarker、Marko、Pug、Jinja2等等,各大 MVVM 框架如 KnockoutJS,Vue,Angular 等也都有自己用來構建使用者介面的內建模板語言。
# Model 層
Model 是指資料模型,泛指後端進行的各種業務邏輯處理和資料操控,主要圍繞資料庫系統展開。後端的處理通常會非常複雜:
後端:我們這裡的業務邏輯和資料處理會非常複雜!
前端:關我屁事!
後端業務處理再複雜跟我們前端也沒有半毛錢關係,只要後端保證對外介面足夠簡單就行了,我請求api,你把資料返出來,咱倆就這點關係,其他都扯淡。
# ViewModel 層
ViewModel 是由前端開發人員組織生成和維護的檢視資料層。
在這一層,前端開發者對從後端獲取的 Model 資料進行轉換處理,做二次封裝,以生成符合 View 層使用預期的檢視資料模型。需要注意的是 ViewModel 所封裝出來的資料模型包括檢視的狀態和行為兩部分,而 Model 層的資料模型是隻包含狀態的,比如頁面的這一塊展示什麼,那一塊展示什麼這些都屬於檢視狀態(展示),而頁面載入進來時發生什麼,點選這一塊發生什麼,這一塊滾動時發生什麼這些都屬於檢視行為(互動),檢視狀態和行為都封裝在了 ViewModel 裡。這樣的封裝使得 ViewModel 可以完整地去描述 View 層。由於實現了雙向繫結,ViewModel 的內容會實時展現在 View 層,這是激動人心的,因為前端開發者再也不必低效又麻煩地通過操縱 DOM 去更新檢視,MVVM 框架已經把最髒最累的一塊做好了,我們開發者只需要處理和維護 ViewModel,更新資料檢視就會自動得到相應更新,真正實現資料驅動開發。看到了吧,View 層展現的不是 Model 層的資料,而是 ViewModel 的資料,由 ViewModel 負責與 Model 層互動,這就完全解耦了 View 層和 Model 層,這個解耦是至關重要的,它是前後端分離方案實施的重要一環。
舉例子:
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 程式設計模式。
程式碼執行之後雙向繫結的效果如下:
搜尋
複製