談MVVM

什麼是MVVM

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

一個事件發生的過程:前端

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

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

三、視圖 V 更新數據,展示給用戶vuex

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

 

概念簡介

一)模型

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

model自己是獨立的,自控的,不依賴於view,可以同步支持多view的顯示。架構

 

二)視圖

視圖是與用戶交互的一層。它是展示一個視圖模型狀態的一個可交互視圖包含數據綁定用戶接口事件,還須要可以理解視圖模型的行爲儘管這些行爲可以被映射到屬性處理這來自視圖模型的事件。mvc

 

三)視圖模型核心

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

例子:有一個對象的日期屬性是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的實踐。

相關文章
相關標籤/搜索