Model-View-View Modal詳解
什麼是MVVM?
MVVM(模型-視圖-視圖模型,Model-View-ViewModal)是一種架構模式,並非一種框架,它是一種思想,一種組織與管理代碼的藝術。它利用數據綁定,屬性依賴,路由事件,命令等特性實現高效靈活的架構
一個事件發生的過程:
1、用戶在視圖V上與應用發生交互
2、VM觸發相應的事件,VM從模型M中請求到用戶需要的數據,並立馬反饋回視圖
3、視圖V更新數據,展現給用戶
Mvvm的核心是數據驅動,實際開發中,只要預先寫好view和model的關係映射(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模式:
View 展示數據
Model 管理數據
Controller 響應用戶操作,並將 Model 更新到 View 上
但是,當應用上升到一個級別時,mvc模式的弊端有3個明顯的問題:
1、代碼中大量調用相同的DOM API,代碼難以維護。
2、大量的DOM操作使頁面載入速度變慢,影響用戶體驗。
3、Model 的頻繁變化,需要開發者主動更新到View;當用戶的操作導致Model發生變化,開發者同樣需要將變化的數據同步到Model中。 當UI狀態一旦多起來時,這些工作不僅繁瑣,而且很難維護複雜多變的數據狀態。
關於對MVC比較詳細的理解,這裡請參考我寫的上一篇文章:簡單談談Mvc
為了解決上述問題,出現了前端界的MVVM。MVVM可以很好的降低我們維護狀態,視圖的複雜程度(大大減少代碼中的視圖更新邏輯)。
下面還是以todoList為demo和上篇文章的例子對比,實現同樣的功能,用到的js代碼不到30行
<template>
<div id="app">
<ul v-for="(item, index) in todoList">
<li @click="remove(index)">{{item.text}}</li>
</ul
<input type="text" v-model="text">
<button @click="add">確認</button>
</div>
</template>
<script>
import store from "./data_store.js"
const TODO_LIST = "__todoList__"
export default {
data() {
return {
text: "",
todoList: store.get(TODO_LIST, [])
}
},
methods: {
add() {
let val = this.todoList.push({
id: Number(new Date()),
text: this.text && this.text.trim()
})
this.text = ""
},
remove(index) {
this.todoList.splice(index, 1)
}
},
watch: {
todoList() {
store.set(TODO_LIST, this.todoList)
}
}
}
</script>
/*
* 只封了 get 與 set
*/
let store = {
storage: window.localStorage
}
const api = {
/*
* @param key 為localStorage 的key值
* @param defaults 當本地存儲的數據為空時的默認值
*/
get(key, defaults) {
let val = deserialize(this.storage.getItem(key))
return val !== undefined ? val : defaults
},
set(key, val) {
if (typeof val === "undefined") {
return this.remove(key)
}
this.storage.setItem(key, serialize(val))
},
remove(key) {
this.storage.removeItem(key)
}
}
function serialize(val) {
return JSON.stringify(val)
}
function deserialize(val) {
if (typeof val !== "string") {
return
}
return JSON.parse(val)
}
Object.assign(store, api)
export default store
解決什麼?
對於有一定數量功能的網頁,合理,高效地組織代碼,是提高開發效率的關鍵所在。在事件管理上面,MV*注重模型的數據改變而觸發各種事件,將數據和事件聯繫起來,數據變動,界面變化。面向數據編程,把所有精力放在數據處理,不關心對網頁元素的處理。MVVM更加便於UI和驅動UI的構造塊,這兩部分的並行開發,抽象視圖使得背後所需要的業務邏輯(或者粘合劑)的代碼數量得以減少,對於持續集成項目,你不光要考慮到初次開發,還要考慮功能演進和可交接性。
從前端地角度,它是UI模式的解決方案,在前端,我們經常要處理數據與界面的關係。m與v的完全脫離,使得開發人員只專於注業務邏輯,抽象的數據,依靠vm與v的雙向綁定,通過改變業務邏輯,界面就自動更新了,尤其方便。故開發人員需要維護的只是抽象數據,通過數據,可以隨時構建出新的UI 。 當UI的狀態一旦多起來時,mvvm這種優勢就體現出來了。
當下優秀的MVVM框架有很多,不同的業務場景採用不同框架,它們有一個始終統一的目的:解放dom操作,面向數據編程。這裡以vue為例,在同一業務邏輯下,通過vue很好地解決了m與v的耦合,其高可復用性,一個viewModal可以復用到多個view視圖上。開發人員只關注viewModal,結合其生態系統中的vue-router與vuex更好地組織代碼。純粹講MVVM的概念太多抽象了,在下一篇文章,我會通過實現一個簡單的vue來模擬mvvm的實踐。
中公優就業IT培訓,總有你想學的:http://xue.ujiuye.com
學IT,還能賺外快,何樂而不為!
http://www.ujiuye.com/zt/qgjx/?wt.bd=mmxtt
找工作太難?不光是幫你幫你就業,還有更多政策!
http://www.ujiuye.com/zt/jycj/?=mmxtt
※文職轉行後月薪一萬,就是有這種操作
※怎樣從零開始搭建一個個人博客?
※Flask01 初識flask、創建flask應用、flask啟動配置
※redis集群搭建及注意事項
TAG:IT優就業 |