談MVVM

来源:http://www.cnblogs.com/LIUYANZUO/archive/2017/09/04/7476544.html
-Advertisement-
Play Games

什麼是MVVM? MVVM(模型-視圖-視圖模型,Model-View-ViewModal)是一種架構模式,並非一種框架,它是一種思想,一種組織與管理代碼的藝術。它利用數據綁定,屬性依賴,路由事件,命令等特性實現高效靈活的架構 一個事件發生的過程: 1、用戶在視圖 V 上與應用發生交互 2、VM 觸 ...


什麼是MVVM

MVVM模型-視圖-視圖模型,Model-View-ViewModal)是一種架構模式,並非一種框架,它是一種思想,一種組織與管理代碼的藝術。它利用數據綁定,屬性依賴,路由事件,命令等特性實現高效靈活的架構

一個事件發生的過程:

1、用戶在視圖 V 上與應用發生交互

2、VM 觸發相應的事件,VM從模型 M 中請求到用戶需要的數據,並立馬反饋回視圖

3、視圖 V 更新數據,展現給用戶

Mvvm的核心是數據驅動,實際開發中,只要預先寫好viewmodel的關係映射(viewmodel),然後viewmodl為核心,從view出發,頁面需要什麼數據,就去model中設置數據源。當發生了用戶事件時,view處理自己的用戶介面事件,並把相關事件映射到視圖模型。viewmodl通知更新model,然後刷新view 從而實現數據雙向綁定更新

 

概念簡介

一)模型

模型持有著應用的多個領域下的相關數據。一個領域相關的數據,說白了,是用戶賬號(名字,頭像,電子郵件)的抽象,或者音樂唱片(唱片名,年代,專輯)的抽象模型是一個領域下的數據及其相關邏輯的抽象。當視圖模型請求數據時,模型將數據包裝成模型實例,

model本身是獨立的,自控的,不依賴於view,能夠同步支持多view的顯示。

 

二)視圖

視圖是與用戶交互的一層。它是展現一個視圖模型狀態的一個可交互視圖包含數據綁定用戶介面事件,還需要能夠理解視圖模型的行為儘管這些行為能夠被映射到屬性處理這來自視圖模型的事件。

 

三)視圖模型核心

視圖模型是一個專門進行數據轉換的控制器。它把對象信息轉換到視圖信息,將命令從視圖攜帶到對象。

例子:有一個對象的日期屬性是unix格式的(e.g 1333832407),不是用戶視圖的所需要的日期格式(e.g 04/07/2012 @ 5:00pm),轉換為視圖需要的格式。我們的對象只簡單保存原始的unix數據格式日期,視圖模型作為一個中間人角色會格式化原始的unix數據格式轉換為視圖需要的日期格式。

在這個場景下,視圖模型相當於一個對象,它處理多視圖顯示邏輯也對外提供更新視圖狀態的方法,並通過視圖方法和觸發事件更新對象。

Vue描述視圖模型作為數據的表現和操作可以在UI上訪問和執行。視圖模型並不是一個UI對象,也不是數據持久化對象,而是一個能夠為用戶提供儲存狀態及操作的層次對象。Vue的視圖模型實現了JavaScript對象與HTML語言無關性。通過這個實現使開發保持了簡單

 

為什麼會出現 MVVM 呢?

一切源於h5的流行,與原生app進行快速迭代。既然要用H5 來構建 App, View 層所做的事,就不僅僅是簡單的數據展示了,它不僅要管理複雜的數據狀態,還要處理移動設備上各種操作行為等等。因此,前端需要工程化,傳統的MVC模式:

    1. View 展示數據
    2. Model 管理數據
    3. Controller 響應用戶操作,並將 Model 更新到 View 上

但是,當應用上升到一個級別時,mvc模式的弊端有3個明顯的問題:

1代碼中大量調用相同的 DOM API,代碼難以維護。

2大量的DOM 操作使頁面載入速度變慢,影響用戶體驗。

3Model 的頻繁變化,需要開發者主動更新到View ;當用戶的操作導致 Model 發生變化,開發者同樣需要將變化的數據同步到Model 。 當UI 狀態一旦多起來時,工作不僅繁瑣,而且很難維護複雜多變的數據狀態。

關於對MVC比較詳細的理解,這裡請參考我寫的上一篇文章簡單談談Mvc

 

為瞭解決上述問題,出現了前端界的MVVMMVVM 可以很好的降低我們維護狀態視圖的複雜程度(大大減少代碼中的視圖更新邏輯)。

下麵還是以todoListdemo和上篇文章的例子對比,實現同樣的功能,用到的js代碼不到30

 1 <template>
 2     <div id="app">
 3         <ul v-for="(item, index) in todoList">
 4             <li @click="remove(index)">{{item.text}}</li>
 5         </ul
 6         <input type="text" v-model="text">
 7         <button @click="add">確認</button>
 8     </div>
 9 </template>
10 
11 <script>
12   import store from './data_store.js'
13 
14   const TODO_LIST = '__todoList__'
15   export default {
16     data() {
17       return {
18         text: '',
19         todoList: store.get(TODO_LIST, [])
20       }
21     },
22 
23     methods: {
24       add() {
25         let val = this.todoList.push({
26           id: Number(new Date()),
27           text: this.text && this.text.trim()
28         })
29         this.text = ''
30       },
31       remove(index) {
32         this.todoList.splice(index, 1)
33       }
34     },
35     watch: {
36       todoList() {
37         store.set(TODO_LIST, this.todoList)
38       }
39     }
40   }
41 </script>
 1 /*
 2  * 只封了 get 與 set
 3  */
 4 let store = {
 5   storage: window.localStorage
 6 }
 7 
 8 const api = {
 9   /*
10    * @param key 為localStorage 的key值
11    * @param defaults 當本地存儲的數據為空時的預設值 
12    */
13   get(key, defaults) {
14     let val = deserialize(this.storage.getItem(key))
15     return val !== undefined ? val : defaults
16   },
17 
18   set(key, val) {
19     if (typeof val === "undefined") {
20      return this.remove(key)
21     }
22     this.storage.setItem(key, serialize(val))
23   },
24 
25   remove(key) {
26     this.storage.removeItem(key)
27   }
28 }
29 
30 function serialize(val) {
31   return JSON.stringify(val)
32 }
33 
34 function deserialize(val) {
35   if (typeof val !== "string") {
36     return
37   }
38   return JSON.parse(val)
39 }
40 
41 Object.assign(store, api)
42 
43 export default store

解決什麼?

    對於一定數量功能的網頁,合理高效組織代碼,是提高開發效率的關鍵所在。在事件管理上面,MV*註重模型的數據改變而觸發各種事件,將數據和事件聯繫起來,數據變動,界面變化。面向數據編程,把所有精力放在數據處理,不關心對網頁元素的處理。MVVM更加便於UI和驅動UI的構造塊這兩部分的並行開發抽象視圖使得背後所需要的業務邏輯(或者粘合劑)的代碼數量得以減少對於持續集成項目,你不光要考慮到初次開發,還要考慮功能演進和可交接性

       從前端地角度,它是UI模式解決方案在前端,我們經常要處理數據與界面的關係。mv的完全脫離,使得開發人員只專於註業務邏輯,抽象的數據,依靠vmv的雙向綁定,通過改變業務邏輯,界面就自動更新了,尤其方便。故開發人員需要維護的只是抽象數據,通過數據,可以隨時構建出新的 UI 。  UI 的狀態一旦多起來mvvm這種優勢就體現出來了。

     當下優秀的MVVM框架有很多,不同的業務場景採用不同框架,它們有一個始終統一的目的:解放dom操作,面向數據編程。這裡以vue為例,在同一業務邏輯下,通過vue很好地解決了mv的耦合,其高可復用性,一個viewModal可以復用到多個view視圖上。開發人員只關註viewModal,結合其生態系統中的vue-routervuex更好地組織代碼。純粹講MVVM的概念太多抽象了,在下一篇文章,我會通過實現一個簡單的vue來模擬mvvm的實踐。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • spring boot / cloud (九) 使用rabbitmq消息中間件 前言 rabbitmq介紹: RabbitMQ是一個在AMQP基礎上完整的,可復用的企業消息系統。它可以用於大型軟體系統各個模塊之間的高效通信,支持高併發,支持可擴展。 amqp介紹: 即Advanced Message ...
  • 映射文件:指導著MyBatis如何進行資料庫增刪改查, 有著非常重要的意義; - cache 命名空間的二級緩存配置 - cache-ref 其他命名空間緩存配置的引用。 - resultMap 自定義結果集映射 - parameterMap 已廢棄!老式風格的參數映射 - sql 抽取可重用語句塊 ...
  • 需要編譯的文件: main.c fun.c fun.h 第一種:makefile 第二種使用變數 第三種自動推導 5.自動化變數 6.自動化變數 7. 生成多個可執行文件 8. 引用其他目錄下的 .h文件 9.編譯不同目錄下的文件 ...
  • 1 數組的定義 2 數組的記憶體分配及特點 3 數組操作常見問題 4 數組常見操作 5 數組中的數組(二維數組) ...
  • endl是 end line的意思,表示此行結束,換行,就是回車 ...
  • #include <iostream>using namespace std; int main(){ //求兩數中的大者? int a,b; cin>>a>>b; if(a>b) cout<<"The max number is:"<<a; else cout<<"The max number i ...
  • https://ngrok.com/ G:\ngrok>ngrok helpNAME: ngrok - tunnel local ports to public URLs and inspect traffic DESCRIPTION: ngrok exposes local networked s ...
  • 先將Spring和Mybatis整合 1.加入 mybatis 的 jar 包和配置文件: 實際上需要配置的就是 settings 的部分。 2. 加入 Spring 的 jar 包和配置文件 之前是在 mybatis-config.xml 獲取 sqlSessionFactory 和掃描 mapp ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...