javascript
WEB前端 从原生JavaScript到MVVM
在了解MVVM之前,我們先回顧一下前端發(fā)展的歷史階段,做到心中有數(shù),才會(huì)更好理解。
這段回顧歷史,由于網(wǎng)上就可查不少資料,但都篇幅很長,晦澀難懂。
所以我引用了 廖雪峰老師網(wǎng)站總結(jié)的一段話,言簡意駭,方便大家秒懂閱讀
在上個(gè)世紀(jì)的1989年,歐洲核子研究中心的物理學(xué)家Tim Berners-Lee發(fā)明了超文本標(biāo)記語言(HyperText Markup Language),簡稱HTML,并在1993年成為互聯(lián)網(wǎng)草案。從此,互聯(lián)網(wǎng)開始迅速商業(yè)化,誕生了一大批商業(yè)網(wǎng)站。
最早的HTML頁面是完全靜態(tài)的網(wǎng)頁,它們是預(yù)先編寫好的存放在Web服務(wù)器上的html文件。
瀏覽器請求某個(gè)URL時(shí),Web服務(wù)器把對應(yīng)的html文件扔給瀏覽器,就可以顯示html文件的內(nèi)容了。
如果要針對不同的用戶顯示不同的頁面,顯然不可能給成千上萬的用戶準(zhǔn)備好成千上萬的不同的html文件,所以,服務(wù)器就需要針對不同的用戶,動(dòng)態(tài)生成不同的html文件。一個(gè)最直接的想法就是利用C、C++這些編程語言,直接向?yàn)g覽器輸出拼接后的字符串。這種技術(shù)被稱為CGI:Common Gateway Interface。
很顯然,像新浪首頁這樣的復(fù)雜的HTML是不可能通過拼字符串得到的。于是,人們又發(fā)現(xiàn),其實(shí)拼字符串的時(shí)候,大多數(shù)字符串都是HTML片段,是不變的,變化的只有少數(shù)和用戶相關(guān)的數(shù)據(jù),所以,又出現(xiàn)了新的創(chuàng)建動(dòng)態(tài)HTML的方式:ASP、JSP和PHP等——分別由微軟、SUN和開源社區(qū)開發(fā)。
在以前:
在ASP中,一個(gè)asp文件就是一個(gè)HTML,但是,需要替換的變量用特殊的<%=var%>標(biāo)記出來了,再配合循環(huán)、條件判斷,創(chuàng)建動(dòng)態(tài)HTML就比CGI要容易得多。
但是,一旦瀏覽器顯示了一個(gè)HTML頁面,要更新頁面內(nèi)容,唯一的方法就是重新向服務(wù)器獲取一份新的HTML內(nèi)容。如果瀏覽器想要自己修改HTML頁面的內(nèi)容,怎么辦?那就需要等到1995年年底,JavaScript被引入到瀏覽器。
有了JavaScript后,瀏覽器就可以運(yùn)行JavaScript,然后,對頁面進(jìn)行一些修改。JavaScript還可以通過修改HTML的DOM結(jié)構(gòu)和CSS來實(shí)現(xiàn)一些動(dòng)畫效果,而這些功能沒法通過服務(wù)器完成,必須在瀏覽器實(shí)現(xiàn)。
以上頁面發(fā)展歷史,摘自廖雪峰總結(jié),有興趣可以去搜
下面先跟著我節(jié)奏揭開MVVM原理。
JavaScript操作HTML
至于 js如何在瀏覽器執(zhí)行,這又是另外一個(gè)資深課題了(前端真的是只是龐雜),這里我們不做研究,有興趣的可以自己去搜資料。我們只需要知道瀏覽器就是也JS執(zhí)行容器,執(zhí)行完之后,通過頁面顯示結(jié)果就行了,就像java需要編譯器一樣原理。
用JavaScript在瀏覽器中操作HTML,也經(jīng)歷了若干發(fā)展階段: 我們利用【小北最帥】這個(gè)案例來展示
【第一階段】
是JS原生通過瀏覽器解析機(jī)制,它的原理是使用瀏覽器提供的原生API 結(jié)合JS語法,可以直接操作DOM,如:
HTML:
<div?id="name"?style="color:#fff">前端你別鬧</div> <div?id="age">3</div>
JavaScript:
// JavaScriptvar?dom1 =?document.getElementById('name');var?dom2 =?document.getElementById('age'); dom1.innerHTML =?'小北'; dom2.innerHTML =?'666'; dom1.style.color =?'#000000'; ?// css樣式也可以操作
結(jié)果變成:
<div?id="name"?style="color:#fff">小北</div> <div?id="age">'666</div>
【第二階段】
我用一個(gè)字總結(jié) 就是懶,就是我們上一篇說的jQuery時(shí)代,由于原生API晦澀難懂,語法很長不好用,最重要的是要考慮各種瀏覽器兼容性,因?yàn)樗麄兊慕馕鰳?biāo)準(zhǔn)都不一樣,造成了,寫一段效果代碼要寫很多的兼容語法,令人沮喪,所以jQuery的出現(xiàn),迅速占領(lǐng)了世界。
上邊的例子用 jQuery 是這樣的
HTML:
<div?id="name"?style="color:#fff">前端你別鬧</div> <div?id="age">3</div>
JavaScript:
// jQuery 一句話就行
$('#name').text('小北好帥').css('color',?'#000000'); $('#age').text('666').css('color',?'#fff');
結(jié)果變成:
<div?id="name"?style="color:#fff">小北好帥</div> <div?id="age">666</div>
【第三階段】
MVC模式,需要服務(wù)器端配合,JavaScript可以在前端修改服務(wù)器渲染后的數(shù)據(jù)。
一句話就是所有通信都是單向的: 也就是前期我們最常用的狀態(tài),提交一次反饋一次,通信一次相互制約。
比如:提交表單 填寫內(nèi)容 → 點(diǎn)擊提交 →業(yè)務(wù)邏輯處理 →存入數(shù)據(jù)庫 → 刷新頁面→服務(wù)器取數(shù)據(jù)庫數(shù)據(jù)→渲染到客戶端頁面→ 展示上一次你提交的內(nèi)容
視圖(View):用戶界面。
控制器(Controller):業(yè)務(wù)邏輯
模型(Model):數(shù)據(jù)保存
各部分之間的通信方式如下。
View 傳送指令到 Controller
Controller 完成業(yè)務(wù)邏輯后,要求 Model 改變狀態(tài)
Model 將新的數(shù)據(jù)發(fā)送到 View,用戶得到反饋
這個(gè)模式缺點(diǎn)是什么呢?
缺點(diǎn)一:它必須等待服務(wù)器端的指示,而且如果是異步模式的話,所有html節(jié)點(diǎn)、數(shù)據(jù)、頁面結(jié)構(gòu)都是后端請求過來。
瀏覽器只作為一個(gè)解析顯示容器,Model 作用幾乎是廢x,Model 層面做的很少幾乎前端無法控制,你前端幾乎是切圖仔和做輪播圖的工作/哭
缺點(diǎn)二:因?yàn)槟闱岸虽秩镜捻撁娼Y(jié)構(gòu),幾乎是后端服務(wù)器包扎一堆數(shù)據(jù)一起發(fā)送過來,前端的你只需要用拼接字符串 或者字符串拼接引擎
?比如Mustache、Jade、artTemplate、tmpl、kissyTemplate、ejs等來做事,說白了純苦力和重復(fù)工作居多,這也導(dǎo)致了,如果很多人認(rèn)為前端并不重要,只負(fù)責(zé)美工 和 動(dòng)作體驗(yàn)就好了。
缺點(diǎn)三:一發(fā)而動(dòng)全身。數(shù)據(jù)、顯示不分離!為什么這么說,因?yàn)槿绻麡I(yè)務(wù)邏輯要變,比如很簡單的需求,你用jsp或者php 拼接出來的ajax數(shù)據(jù)頁面,年齡這個(gè)字段我不需要了,把性別字段 區(qū)分開,男的單獨(dú)顯示,女的單獨(dú)顯示,以前是一起顯示到一個(gè)表的
那么,后端先要sql查詢把 男、女?dāng)?shù)據(jù)分開,然后渲染字符串時(shí)候把 年齡 這個(gè)字段去除,然后把男女分開成2個(gè)table,然后再推送給前端接收。
前端收到了,然后從新在渲染一遍,在加工一次頁面甚至是展示動(dòng)作效果。。。真苦逼啊(前后端一起大聲喊到:加班使我快樂,嗚嗚嗚)
MVVM框架模式
終于來到【第四階段】,為什么在MVC模式我說這么多廢話呢,因?yàn)槟懔私饬薓VC才能更清楚的知道
「 何為mvvm模式 」
MVVM最早由微軟提出來,它借鑒了桌面應(yīng)用程序的MVC思想,在前端頁面中,把Model用純JavaScript對象表示,View負(fù)責(zé)顯示,兩者做到了最大限度的分離。也就是我們常說的,前后分離,真正在這里得以實(shí)現(xiàn)
它采用雙向綁定(data-binding):View的變動(dòng),自動(dòng)反映在 ViewModel,反之亦然,model數(shù)據(jù)的變動(dòng),也自動(dòng)展示給頁面顯示
把Model和View關(guān)聯(lián)起來的就是ViewModel。ViewModel負(fù)責(zé)把Model的數(shù)據(jù)同步到View顯示出來,還負(fù)責(zé)把View的修改同步回Model。
可能理論知識枯燥無味,那么我們還是實(shí)戰(zhàn)派,來看代碼不就好了嗎?
還是剛才的 【小北最帥】案例
js和jQuery的寫法 大家也看到了,那么我們來MVVM 數(shù)據(jù)綁定怎么實(shí)現(xiàn)。
由于數(shù)據(jù)驅(qū)動(dòng)模式的精髓在于【數(shù)據(jù)】和【視圖】分離,所以我們首先并不關(guān)心DOM結(jié)構(gòu),而是關(guān)心數(shù)據(jù)的展現(xiàn)。
最簡單的數(shù)據(jù)存儲(chǔ)方式是什么呢?顯然不是mysql、數(shù)據(jù)庫而是使用JavaScript對象
HTML:
// 這次我不關(guān)心你了,哼哼
JavaScript:
// JS基礎(chǔ)對象// 原始數(shù)據(jù)
var?xiaobei = { ? ?name:?'前端你別鬧', ? ?age:?3, ? ?
? ?tag:'干貨'
};
結(jié)果是:
name:?前端你別鬧
age:?3
tag:?干貨
假設(shè):
我們把變量xiaobei 看作Model數(shù)據(jù),把HTML某些DOM節(jié)點(diǎn)看作View,并意淫它們已經(jīng)通過某種手段被關(guān)聯(lián)起來了。
下面我們把name 從[ 前端你別鬧] 改為 [小北],把顯示的age從 [3] 改為 [666],tag變成 [最帥!]
按照以前我們肯定操作DOM節(jié)點(diǎn),而現(xiàn)在我們只需要修改JavaScript對象:
JavaScript:
// JS基礎(chǔ)對象// 改變的數(shù)據(jù)
var?xiaobei = { ? ?name:?'小北', ? ?age:?666, ? ?
? ?tag:'最帥'
};
結(jié)果是:
name:?小北
age:?666
tag:?最帥
通過實(shí)驗(yàn)和理論
小伙伴驚呆了,我們只要改變JavaScript對象的內(nèi)容,就會(huì)導(dǎo)致DOM結(jié)構(gòu)作出對應(yīng)的變化!
這讓我們的關(guān)注點(diǎn)從如何操作DOM變成了如何改變JavaScript對象的狀態(tài),而操作JavaScript對象比獲取和操作DOM簡單了一個(gè)地球的距離!
這也是MVVM的核心思想:關(guān)注Model的變化,讓MVVM框架利用自己的機(jī)制去自動(dòng)更新DOM,從而把開發(fā)者從操作DOM的繁瑣中解脫出來!
也就是所謂的 數(shù)據(jù) - 視圖分離,數(shù)據(jù)驅(qū)動(dòng)視圖, 視圖不影響數(shù)據(jù),再也不用管繁瑣的DOM結(jié)構(gòu)操作了,世界頓時(shí)清凈,完美!
常見的MVVM框架:Vue.JS、AngularJs、reactJs 等我們在下一篇討論
結(jié)尾
好累,終于通過簡單的例子和很白話的語言,引出了mvvm框架話題,大牛請忽略,也別笑我,我只是用最簡單易懂的語言和表達(dá),讓更多的人看明白原理,才好進(jìn)行實(shí)際應(yīng)用,其實(shí)沒什么技術(shù)難點(diǎn)。
總結(jié)
以上是生活随笔為你收集整理的WEB前端 从原生JavaScript到MVVM的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 灵锡app
- 下一篇: JS事件委托的概念和作用