1. 程式人生 > 其它 >MVVM框架

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 程式設計模式。

程式碼執行之後雙向繫結的效果如下:

搜尋

複製