“约见”面试官系列之常见面试题之第九十四篇之MVVM框架(建议收藏)
目錄
一句話總結:vm層(視圖模型層)通過接口從后臺m層(model層)請求數據,vm層繼而和v(view層)實現數據的雙向綁定。
1、我大前端應該不應該做復雜的數據處理的工作?
2、mvc和mvvm的關系?
3、MVVM框架編碼實例?
4、前端框架MVVM出現的最大意義是什么?
5、應用MVVM框架的vue.js框架的最主要作用是什么?
6、前端框架MVVM中的vm層是干嘛的?
7、MVVM最主要的特征是什么?
二、MVVM百度百科
三、前后端分手大師——MVVM 模式(轉)
簡而言之
組成部分
沒有什么是一個栗子不能解決的
四、不要聽吹牛逼什么前端MVVM框架就是好,其實都是一幫沒學好分層設計的搞出來的,讓你徹底看清前端MVVM的本質(轉)
?一、總結(點擊顯示或隱藏總結內容)
一句話總結:vm層(視圖模型層)通過接口從后臺m層(model層)請求數據,vm層繼而和v(view層)實現數據的雙向綁定。
?
1、我大前端應該不應該做復雜的數據處理的工作?
不應該
只要后端保證對外接口足夠簡單就行了,我請求api,你把數據返出來,咱倆就這點關系,其他都扯淡。
后端:我們這里的業務邏輯和數據處理會非常復雜!
前端:關我屁事!
后端業務處理再復雜跟我們前端也沒有半毛錢關系,只要后端保證對外接口足夠簡單就行了,我請求api,你把數據返出來,咱倆就這點關系,其他都扯淡。
?
所以我這邊開發也是同樣的,前端就負責請求api就好,別的都不需要。
?
2、mvc和mvvm的關系?
改進版
數據分離
視圖模型層
c(控制層)被換成了vm(viewmodel)層
MVVM是Model-View-ViewModel的簡寫。它本質上就是MVC 的改進版。
mvvm層實現了前后端更好的分離(前端需要的數據只需要請求后端的接口即可)
?
3、MVVM框架編碼實例?
扯了這么多,并沒有什么卵用。千言萬語不如一個栗子來的干脆,下面用一個 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 編程模式。
?
4、前端框架MVVM出現的最大意義是什么?
開發效率
前后端 業務邏輯 分離
接口
MVVM 的出現促進了 GUI 前端開發與后端業務邏輯的分離,極大地提高了前端開發效率。
MVVM用接口實現了前后端數據的通信,這樣可以使前后端之間的業務邏輯沒有什么關系。
MVVM在感覺上要比mvc模式前后端要分的更開
?
5、應用MVVM框架的vue.js框架的最主要作用是什么?
雙向數據綁定
前端數據的統一
前端數據的統一:前端應用相同數據的位置實現了數據的統一
雙向數據綁定:綁定后vue好dom數據保持統一,一動全動,是前端的
雙向數據綁定中的兩向分別為 view和viewmodel。
?
6、前端框架MVVM中的vm層是干嘛的?
狀態 行為
DOM操作
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做交互
?
7、MVVM最主要的特征是什么?
前后端分離
前后端分手大師——MVVM 模式
或者說前后端更好的分離(接口來實現前后端的通信)
?
?
?
回到頂部
二、MVVM百度百科
MVVM是Model-View-ViewModel的簡寫。它本質上就是MVC 的改進版。MVVM 就是將其中的View 的狀態和行為抽象化,讓我們將視圖 UI 和業務邏輯分開。當然這些事 ViewModel 已經幫我們做了,它可以取出 Model 的數據同時幫忙處理 View 中由于需要展示內容而涉及的業務邏輯。微軟的WPF帶來了新的技術體驗,如Silverlight、音頻、視頻、3D、動畫……,這導致了軟件UI層更加細節化、可定制化。同時,在技術層面,WPF也帶來了 諸如Binding、Dependency Property、Routed Events、Command、DataTemplate、ControlTemplate等新特性。MVVM(Model-View-ViewModel)框架的由來便是MVP(Model-View-Presenter)模式與WPF結合的應用方式時發展演變過來的一種新型架構框架。它立足于原有MVP框架并且把WPF的新特性糅合進去,以應對客戶日益復雜的需求變化。
外文名
Model-View-ViewModel
簡????稱
MVVM
例????如
Silverlight、音頻
隸????屬
微軟
MVVM優點
低耦合?可重用性
?
回到頂部
三、前后端分手大師——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 層
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 實例來說明 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的本質(轉)
轉自:不要聽吹牛逼什么前端MVVM框架就是好,其實都是一幫沒學好分層設計的搞出來的,讓你徹底看清前端MVVM的本質 - 薛端陽 - 博客園
https://www.cnblogs.com/xueduanyang/p/3601471.html
最近前端圈子里面,發現大家都在熱炒概念,什么knockout,angularJs,都被捧成神了,鄙人不才,最近心情也不好,特地寫這篇文章來找罵
寫代碼的碼農都知道,Java社區雖然不是一個提出分層思想的,確實貫徹的最好的,如今是個Java開發都不會不知道SSH的開發模式,從MVC到MVVM的概念的熱炒,其實真沒什么技術進步
?
先看什么是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框架(建议收藏)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: eoLinker-API_Shop_知识
- 下一篇: 网络通信原理及流程