只要後端保證對外接口足夠簡單就好了,我請求api,你把數據返出來,咱倆就這點關係,其餘都扯淡。html
後端:咱們這裏的業務邏輯和數據處理會很是複雜!
前端:關我屁事!前端
後端業務處理再複雜跟咱們前端也沒有半毛錢關係,只要後端保證對外接口足夠簡單就好了,我請求api,你把數據返出來,咱倆就這點關係,其餘都扯淡。vue
因此我這邊開發也是一樣的,前端就負責請求api就好,別的都不須要。java
c(控制層)被換成了vm(viewmodel)層web
MVVM是Model-View-ViewModel的簡寫。它本質上就是MVC 的改進版。ajax
mvvm層實現了先後端更好的分離(前端須要的數據只須要請求後端的接口便可)數據庫
扯了這麼多,並無什麼卵用。千言萬語不如一個栗子來的乾脆,下面用一個 Vue 實例來講明 MVVM 的具體表現。編程
Vue 的 View 模板:json
<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 編程模式。
MVVM 的出現促進了 GUI 前端開發與後端業務邏輯的分離,極大地提升了前端開發效率。
MVVM用接口實現了先後端數據的通訊,這樣可使先後端之間的業務邏輯沒有什麼關係。
MVVM在感受上要比mvc模式先後端要分的更開
前端數據的統一:前端應用相同數據的位置實現了數據的統一
雙向數據綁定:綁定後vue好dom數據保持統一,一動全動,是前端的
雙向數據綁定中的兩向分別爲 view和viewmodel。
ViewModel 是由前端開發人員組織生成和維護的視圖數據層。在這一層,前端開發者對從後端獲取的 Model 數據進行轉換處理,作二次封裝,以生成符合 View 層使用預期的視圖數據模型。須要注意的是 ViewModel 所封裝出來的數據模型包括視圖的狀態和行爲兩部分,而 Model 層的數據模型是隻包含狀態的,好比頁面的這一塊展現什麼,那一塊展現什麼這些都屬於視圖狀態(展現),而頁面加載進來時發生什麼,點擊這一塊發生什麼,這一塊滾動時發生什麼這些都屬於視圖行爲(交互),視圖狀態和行爲都封裝在了 ViewModel 裏。這樣的封裝使得 ViewModel 能夠完整地去描述 View 層。因爲實現了雙向綁定,ViewModel 的內容會實時展示在 View 層,這是激動人心的,由於前端開發者不再必低效又麻煩地經過操縱 DOM 去更新視圖,MVVM 框架已經把最髒最累的一塊作好了,咱們開發者只須要處理和維護 ViewModel,更新數據視圖就會自動獲得相應更新,真正實現數據驅動開發。看到了吧,View 層展示的不是 Model 層的數據,而是 ViewModel 的數據,由 ViewModel 負責與 Model 層交互,這就徹底解耦了 View 層和 Model 層,這個解耦是相當重要的,它是先後端分離方案實施的重要一環。
View通常就是咱們日常說的HTML文本的Js模板,裏面能夠嵌入一些js模板的代碼,好比Mustache,好比jstl相似的模板僞代碼
ViewModule層裏面就是咱們對於這個視圖區域的一切js可視業務邏輯,舉個例子,好比圖片走馬燈特效,好比表單按鈕點擊提交,這些自定義事件的註冊和處理邏輯都寫在ViewModule裏面了
Module就更簡單了,就是對於純數據的處理,好比增刪改查,與後臺CGI作交互
先後端分手大師——MVVM 模式
或者說先後端更好的分離(接口來實現先後端的通訊)
轉自:先後端分手大師——MVVM 模式 - DOM哥 - 博客園
https://www.cnblogs.com/iovec/p/7840228.html
以前對 MVVM 模式一直只是模模糊糊的認識,正所謂沒有實踐就沒有發言權,經過這兩年對 Vue 框架的深刻學習和項目實踐,終於能夠裝B了有了撥開雲霧見月明的感受。
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模式
MVVM 已經至關成熟了,主要運用但不只僅在網絡應用程序開發中。KnockoutJS 是最先實現 MVVM 模式的前端框架之一,當下流行的 MVVM 框架有 Vue,Angular 等。
簡單畫了一張圖來講明 MVVM 的各個組成部分:
MVVM分層示意圖
分層設計一直是軟件架構的主流設計思想之一,MVVM 也不例外。
View 是視圖層,也就是用戶界面。前端主要由 HTML 和 CSS 來構建,爲了更方便地展示 ViewModel 或者 Model 層的數據,已經產生了各類各樣的先後端模板語言,好比 FreeMarker、Marko、Pug、Jinja2等等,各大 MVVM 框架如 KnockoutJS,Vue,Angular 等也都有本身用來構建用戶界面的內置模板語言。
Model 是指數據模型,泛指後端進行的各類業務邏輯處理和數據操控,主要圍繞數據庫系統展開。後端的處理一般會很是複雜:
先後端對比
後端:咱們這裏的業務邏輯和數據處理會很是複雜!
前端:關我屁事!
後端業務處理再複雜跟咱們前端也沒有半毛錢關係,只要後端保證對外接口足夠簡單就好了,我請求api,你把數據返出來,咱倆就這點關係,其餘都扯淡。
ViewModel 是由前端開發人員組織生成和維護的視圖數據層。在這一層,前端開發者對從後端獲取的 Model 數據進行轉換處理,作二次封裝,以生成符合 View 層使用預期的視圖數據模型。須要注意的是 ViewModel 所封裝出來的數據模型包括視圖的狀態和行爲兩部分,而 Model 層的數據模型是隻包含狀態的,好比頁面的這一塊展現什麼,那一塊展現什麼這些都屬於視圖狀態(展現),而頁面加載進來時發生什麼,點擊這一塊發生什麼,這一塊滾動時發生什麼這些都屬於視圖行爲(交互),視圖狀態和行爲都封裝在了 ViewModel 裏。這樣的封裝使得 ViewModel 能夠完整地去描述 View 層。因爲實現了雙向綁定,ViewModel 的內容會實時展示在 View 層,這是激動人心的,由於前端開發者不再必低效又麻煩地經過操縱 DOM 去更新視圖,MVVM 框架已經把最髒最累的一塊作好了,咱們開發者只須要處理和維護 ViewModel,更新數據視圖就會自動獲得相應更新,真正實現數據驅動開發。看到了吧,View 層展示的不是 Model 層的數據,而是 ViewModel 的數據,由 ViewModel 負責與 Model 層交互,這就徹底解耦了 View 層和 Model 層,這個解耦是相當重要的,它是先後端分離方案實施的重要一環。
扯了這麼多,並無什麼卵用。千言萬語不如一個栗子來的乾脆,下面用一個 Vue 實例來講明 MVVM 的具體表現。
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 編程模式。
代碼執行以後雙向綁定的效果以下:
Vue實現的響應的數據綁定
嘿嘿,先後端能夠成功分手了,之後不再用關心後端個錘子開發進度\暴怒臉,複雜實現,blabla...,盡情享用前端如絲般順滑的開發快感吧:)
轉自:不要聽吹牛逼什麼前端MVVM框架就是好,其實都是一幫沒學好分層設計的搞出來的,讓你完全看清前端MVVM的本質 - 薛端陽 - 博客園
https://www.cnblogs.com/xueduanyang/p/3601471.html
最近前端圈子裏面,發現你們都在熱炒概念,什麼knockout,angularJs,都被捧成神了,鄙人不才,最近心情也很差,特意寫這篇文章來找罵
寫代碼的碼農都知道,Java社區雖然不是一個提出分層思想的,確實貫徹的最好的,現在是個Java開發都不會不知道SSH的開發模式,從MVC到MVVM的概念的熱炒,其實真沒什麼技術進步
(若是你以爲本文言辭激烈,過於憤世嫉俗,實在看不下去,歡迎移步另外一位園友的分層進化史科普文章http://www.cnblogs.com/indream/p/3602348.html)
先看什麼是MVVM
View通常就是咱們日常說的HTML文本的Js模板,裏面能夠嵌入一些js模板的代碼,好比Mustache,好比jstl相似的模板僞代碼
ViewModule層裏面就是咱們對於這個視圖區域的一切js可視業務邏輯,舉個例子,好比圖片走馬燈特效,好比表單按鈕點擊提交,這些自定義事件的註冊和處理邏輯都寫在ViewModule裏面了
Module就更簡單了,就是對於純數據的處理,好比增刪改查,與後臺CGI作交互
那麼什麼是MVVM框架呢??通常他們都是這麼作的
1. 定義一串所謂的僞模板代碼,例如經過className標註,或者自定義tag的方式,將一段html文本區域給標註聲明起來,意思就是喊一嗓子,「喂,兄弟們,這塊地方我佔了,要拉屎去別處拉去」
2. 經過相似jstl之類lamda表達式,來作js模板,「拜託夥計,天堂有路你不走,非要本身搞一套,你就不能暴露接口讓你們用本身的模板語言,好比Mustache或者jtpl嗎?」
3. 很傻比的封裝一串本身的所謂數據模塊組件,與不一樣類型的數據源作數據傳輸和適配,通常都不會分層很清晰,加入後臺數據字段改了,寫框架的都沒腦子的,歷來不作數據字段的自定義適配(舉個例子,原來後臺傳遞的字段是person.userName,如今改爲了小寫,person.username,你就傻逼的去吧模板再改一下吧,其實要解決這個問題,很是簡單,在MVVM層中引入一層DO,領域對象層,Module到DO之間還有一層轉換就能夠搞定這個問題)
4. 非不暴露本身的自定義事件模型,就是那個觀察者模式啦,本身亂七八招在頁面上綁定一堆form change之類的事件,以實現View與Module的單向綁定
5. 所謂的雙向綁定,也就是OOP語言中早被爛透了的getter,setter模型,ES5+能夠用defineProperty,低版本就須要本身在js object賦值的時間作寫死代碼方式的處理了
咱們再來看細節
1. 雙向綁定
號稱是最難理解的地方,實際上是框架的做者根本就沒理解Java社區對於軟件開發分層理解的精髓
標準的數據驅動開發,應該如上圖所示,在一個View的生命週期內,一個ViewModule會管理一個DomainObject(業務模型),一個DO可能包括多個Module數據模型,一個Module可能來自多個數據源,而不是想不少所謂的MVVM框架那樣強迫一個M來一個數據源
按照上圖標準分層方式來劃分的好處,在於,邏輯清晰,Module層粒度夠細,能夠被屢次複用
DO層與VM層View層屬於一一對應關係,方便對數據作增刪改查的同步
每一層應該是獨立的,非必定要使用MVVM框架的緊耦合,能夠用本身使用不一樣的js插件或者模塊實現MVVM
咱們拋棄框架,單純的看數據,其實咱們要解決的問題很簡單
a) 當DO對象屬性放生變化時候,通知View更新
b) 當View上表單值放生變化時,通知DO更新,並異步通知隊列同步到數據源
先來看問題a,這個最簡單,DO是一個基本的Javascript Object,咱們在View上的模板顯示是這個Object.property,
改變一個Object對象的方式無非幾種,一種是
a) 顯示Object.property = ‘我是傻逼’
b) xxxx.methodName(Object, ‘property’, ‘我是傻逼’)
c) xxxx.merge(Object, {‘property’: ‘我是傻逼’})
若是是a的狀況,ES5+,能夠經過設置Object.defefineProperty(‘property’,{set: functiono(){},get:function(){}}),來作賦值和取值的監控觸發
對於IE8一下,由於js不支持運算符重載,因此暫時沒有好的辦法,因此若是隻考慮移動端的話,直接defineProperty就所有搞定,若是是要考慮PC的話,就不建議開發者使用直接賦值的方式,參考java的開發模式,也是推薦OOP時候,使用set方式賦值,而不是直接=賦值
固然了,若是你非要兼容IE8一下的話,用定時器作輪訓,配合for in 反射,經過髒數據與原始備份對比的方法也是一種辦法,不過這種辦法在當前頁面很是耗性能,因爲IE8一下不支持多線程,HTML5 worker,若是將來flash 插件支持多線程的話,卻是能夠用js和flash插件作線程交互的方式作髒數據檢測
若是是b的狀況,那就太簡單了,在methodName裏面觸發對於該屬性修改的回調便可,如何註冊回調呢,首先咱們要實現一個相似Dom Event的自定義對象的Event模型,而後經過相似Dom Event的註冊事件方式,註冊觀察者,訂閱事件,當執行了methodName時候,發送消息,通知全部訂閱者執行回調
若是是c的狀況,相似b同樣處理
這樣一看,雙向數據綁定的問題就很是簡單的解決了
咱們再來看另一個MVVM的問題,非簡單數據模型,複合數據模型(DO的屬性值不是一個string,而是一個Object,且這個Object可能還嵌套多層Obejct的時候)的處理辦法,這個通常的MVVM框架直接不考慮,或者經過長字段名的方式繞過這個問題
這個問題是這樣的,早在10幾年前,java structs框架流行的時候就出現了,當一個表單,出現須要對兩個Java Bean作update操做時候,一個bean是user,一個bean是成績
對應的表單字段名,就是 user表.name,user表.id,score表.point,
在struct2裏面,處理邏輯是把 「點」做爲特殊符號,在作form序列化時候,非包含點的字段的值都是string,包含點的字段是一個Object,好比剛纔的form序列化以後結果就是 { user: {id :’’ , name: ‘’}, score: {id: ‘’, point: ‘’}}
同理在MVVM實現時,也是同樣,認爲點是分割對象的關鍵字,這樣咱們就能夠實現把多個對象嵌套到View模板裏面,實現複合Object的雙向映射
最後一個問題,也就是高級MVVM編程裏面必需要面對的問題,就是自定義事件的廣播和冒泡,我看過大多數的MVVM框架,對於廣播,這塊有部分實現了,可是對於冒泡一個都沒實現
其實這個真的不是很複雜的問題,事件廣播,這個最簡單,三歲小孩都能寫,咱們在註冊回調時候,不是有一個事件隊列嗎,在回調時候,經過特殊標記位,控制是否繼續擴散廣播,仍是執行完畢終止便可
而自定義事件的冒泡要騷騷複雜一些,他是因爲OOP編程裏面的繼承和包含關係引伸而來的,咱們先說包含關係,前面說了MVVM框架裏面,都會聲明一塊地方爲VM控制區域,通常垃圾的框架都不會考慮,VM嵌套的狀況,由於圖簡單嗎
可是實際開發過程當中,你會遇到不少這種狀況,就是VM複用的問題,通常都是發現使用了MVVM框架以後,發現VM定義的太大,無法複用,若是要複用VM就又發現VM定義的過小,出現須要VM嵌套的狀況無法用
其實簡單,咱們知道DOM事件是有冒泡的,VM同理,只要在自定義事件模型裏面定義了VM的父子關係,或者同級關聯關係,便可實現VM的自定義事件的廣播和冒泡,另外也解決了VM複用的問題,可讓代碼顆粒度更小
另外那種,聲明式編程這種老掉牙的概念就真的別在吵了,還記得10幾年前的structs的tag嗎,js圈子裏面這種經過自定義tag,自定義className,自定義屬性,掛載js來自定識別執行邏輯的例子大把皆是,仍是建議廣大前端開發,不要浮躁,多像java社區學習,多多從根本上了解分層理念的精髓,不要聽了吹牛逼,聽風就是雨,仍是多瞭解原理纔是真理啊
最近心情很很差,股票大跌,公司的事情你懂的,寫這篇文檔純屬沒事找事,歡迎廣大道友開罵,來陪我大戰三百回合
轉自:MVVM核心概念 - iammackong - 博客園
https://www.cnblogs.com/iammackong/articles/3312565.html
MVVM模式是Model、View、ViewModel的簡稱,最先出如今WPF,如今Silverlight中也使用該模式,MVVM模式是對MVC模式的變種。哪兒變了?我認爲MVVM和MVC的主要變化在於MVVM更適合於XAML。
1. 低耦合。視圖(View)能夠獨立於Model變化和修改,一個ViewModel能夠綁定到不一樣的"View"上,當View變化的時候Model不能夠不變,當Model變化的時候View也能夠不變。
2. 可重用性。你能夠把一些視圖邏輯放在一個ViewModel裏面,讓不少view重用這段視圖邏輯。
3. 獨立開發。開發人員能夠專一於業務邏輯和數據的開發(ViewModel),設計人員能夠專一於頁面設計,使用Expression Blend能夠很容易設計界面並生成xaml代碼。
4. 可測試。界面素來是比較難於測試的,而如今測試能夠針對ViewModel來寫。
若是用Interface接口來表達,基本就是這麼個意思:
1. View
2. ViewModel
3. Model
View和ViewModel主要經過數據綁定和Command/Behavior進行交互,以下圖所示:
前面說的Model是客戶端的,但實際上Domail Model存在服務器端(靠近數據庫)和那就須要和客戶端搞映射DTO(Data Transfer Ojbect,數據傳輸對象,帶序列化標記,用來遠程調用)。在Silverlight中有個很方便的東西來實現這個DTO過程和序列化,那就是WCF RIA Service和DomainService。若是你建立一個簡單的Silverlight應用而且調用WCF RIA Service,基本上會生成DTO Model: ObjectContext(EntityObject)。(也有人喜歡在Model裏面調用RiaSerivce實現load,save等等,我的認爲不太合適,能夠參考這篇文章),此外,參考這篇文章:《WCF RIA Services and a guide to use DTO/」Presentation Model」》
代碼例:
1. View分離要完全,不要有壞味道
視圖(view)部分,xaml.cs 應該只有不多的代碼或沒有代碼,若是你的xaml.cs包含大量的代碼,那麼極可能你MVVM用的不對頭,須要檢查其中代碼的壞味道。Xaml和xaml.cs 只能包含處理界面、視圖、顯示樣式、視圖元素之間的交互、視圖元素動畫,等等的內容。
2. ViewModel要可測試
從重構的觀點看,若是你的代碼中ViewModel是可測試的,有詳細的單元測試Unit Test,你的代碼是OK的,不然須要檢查其中的壞味道。
更多MVVM的內容且看下回分解。(附:本例子且附代碼下載(Command未示例),channel9有一個MVVM的視頻很好,PPT和視頻演示的源碼)