摘要:原來(lái)是在改變數(shù)據(jù)時(shí),還要手動(dòng)?,F(xiàn)在只需要直接改變數(shù)據(jù),會(huì)自動(dòng),更新元素。參考資料現(xiàn)代前端技術(shù)解析,張成文,年月第版,和的圖示,阮一峰,年月日,
author: 陳家賓 email: 617822642@qq.com date: 2018/3/1MVVM 背景
都說(shuō)懶惰使人進(jìn)步,MVVM 的進(jìn)化史,正印證了這句話,是一步步讓開(kāi)發(fā)人員更懶惰更簡(jiǎn)單的歷史:
直接 DOM 操作 -> MVC -> MVP -> MVVM
最開(kāi)始的前端交互,是很直接的 DOM 操作,最出名的這類庫(kù)當(dāng)數(shù) jQuery 了,封裝了 DOM API,讓一切 DOM 操作都變得簡(jiǎn)單。
但當(dāng)頁(yè)面數(shù)據(jù)和交互多的時(shí)候,散亂的代碼將使項(xiàng)目變得難以維護(hù),讓人發(fā)狂。所以才有了 MV* 模式的發(fā)展。
MV* 模式MVC & MVP & MVVM 三者對(duì)比偽代碼:點(diǎn)我MVC
Model:數(shù)據(jù)模型 & 手動(dòng)渲染模板
View:模板
Controller:修改數(shù)據(jù)
MVPModel:數(shù)據(jù)模型
View:模板
Presenter:修改數(shù)據(jù) & 手動(dòng)渲染模板
MVP 是 MVC 模式的一種改造(這里不說(shuō)改進(jìn),是因?yàn)閮烧咂鋵?shí)很相似,沒(méi)有本質(zhì)上的變化),將 手動(dòng)渲染 步驟** 從 Model 移到了 Presenter,讓 View 和 Model 更獨(dú)立更存粹了,但從另一個(gè)角度來(lái)說(shuō),也加大了 Presenter 的工作。
MVVMModel:數(shù)據(jù)模型
View:帶特殊屬性的 html 模板
ViewModel:依靠 Directive,修改數(shù)據(jù) & 自動(dòng)渲染
MVVM 模式依靠 Directive,實(shí)現(xiàn)了 模板自動(dòng)渲染,極大地解放了開(kāi)發(fā)者的雙手,此時(shí)開(kāi)發(fā)者只需關(guān)注 View 和 Model,效率和可維護(hù)性方面達(dá)到了飛躍式的進(jìn)步。
下面將著重介紹下神奇的 Directive。
數(shù)據(jù)變更檢測(cè)方案(Directive) (一)手動(dòng)觸發(fā)綁定在頁(yè)面需要改變時(shí),手動(dòng)觸發(fā)檢測(cè),改變 model 數(shù)據(jù),并掃描元素,對(duì)有特殊標(biāo)記的元素進(jìn)行修改
let data = { value: "hello" }; let directive = { html: function (html) { this.innerHTML = html; }, value: function (html) { this.setAttribute("value", value); } }; ViewModelSet("value", "hello world"); function ViewModelSet(key, value) { data[key] = value; scan(); } function scan() { for (let elem of elems) { elem.directive = []; for (let attr of elem.attributes) { if (attr.nodeName.indexOf("v-") >= 0) { directive[attr.nodeName.slice(2)].call(elem, data[attr.nodeValue]); } } } }(二)臟檢測(cè)機(jī)制
針對(duì)手動(dòng)綁定進(jìn)行優(yōu)化,只對(duì)修改到的數(shù)據(jù)進(jìn)行更新元素
function scan(elems, val) { let list = document.querySelectorAll(`[v-bind=${val}]`); // 只掃描修改到的數(shù)據(jù)涉及的元素 for (let elem of elems) { for (let attr of elem.attributes) { let dataKey = elem.getAttribute("v-bind"); if (elem.directive[attr.nodeValue] !== data[dataKey]) { // 當(dāng)元素值有變時(shí),更新元素 directive[attr.nodeValue].call(elem, data[dataKey]); elem.directive[attr.nodeValue] = data[dataKey]; // 保存元素當(dāng)前值 } } } }(三)前端數(shù)據(jù)對(duì)象劫持(Hijacking)
在上面的基礎(chǔ)更進(jìn)一步,使用 Object.defineProperty 對(duì)數(shù)據(jù)進(jìn)行 get & set 監(jiān)聽(tīng),當(dāng)數(shù)據(jù)有變時(shí),自動(dòng)執(zhí)行 scan 掃描并更新元素。
原來(lái)是在改變數(shù)據(jù)時(shí),還要手動(dòng) scan。現(xiàn)在只需要直接改變數(shù)據(jù),會(huì)自動(dòng) scan,更新元素。
defineGetAndSet(data, "value"); data.value = "hello world"; function defineGetAndSet(obj, propName) { Object.efineProperty(obj, propName, { get: function () { return this.bVal; }, set: function (newVal) { this.bVal = newVal; scan(); }, enumerable: true, configurable: true }); }(四)ECMAScript 6 Proxy
與方法三類似,換了種寫(xiě)法,這里應(yīng)用了 ES6 里的 Proxy
let data = new Proxy({ get: function (obj, key) { return obj[key]; }, set: function (obj, key, val) { obj[key] = val; scan(); return obj[key]; } });
以上。
參考資料《現(xiàn)代前端 技術(shù)解析》,張成文,2017 年 4 月第 1 版d
《MVC,MVP 和 MVVM 的圖示》,阮一峰,2015年2月 1日,http://www.ruanyifeng.com/blo...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/93034.html
摘要:小白一枚,一直使用的是,想要多了解一些其它的框架,正好最近越來(lái)越火熱,上的數(shù)已經(jīng)超過(guò)了??蚣芾斫庹f(shuō)起這個(gè)模型,就不得不說(shuō)框架。函數(shù)表示創(chuàng)建一個(gè)文本節(jié)點(diǎn),函數(shù)表示創(chuàng)建一個(gè)數(shù)組。 小白一枚,一直使用的是React,想要多了解一些其它的框架,正好最近Vue越來(lái)越火熱,Github上的Star數(shù)已經(jīng)超過(guò)了React。而其背后蘊(yùn)含的MVVM框架思想也一直跟React的組件化開(kāi)發(fā)思想并駕齊驅(qū),在這...
摘要:前言這次找工作也面了好幾家公司,也通過(guò)了好幾家公司的面試,畢竟之前也準(zhǔn)備了一段時(shí)間,所以面試的時(shí)候心里也不是很虛。的代碼分割怎么實(shí)現(xiàn)的說(shuō)說(shuō)剛才提到的和的區(qū)別前端緩存怎么實(shí)現(xiàn)扯扯強(qiáng)緩存和協(xié)商緩存,重點(diǎn)問(wèn)了如何實(shí)現(xiàn)緩存二面就聊了項(xiàng)目。。。 前言 這次找工作也面了好幾家公司,也通過(guò)了好幾家公司的面試,畢竟之前也準(zhǔn)備了一段時(shí)間,所以面試的時(shí)候心里也不是很虛。 這里記錄一下面試過(guò)程中被問(wèn)到的問(wèn)題...
摘要:前端的發(fā)展歷程什么是前端前端針對(duì)瀏覽器的開(kāi)發(fā),代碼在瀏覽器運(yùn)行后端針對(duì)服務(wù)器的開(kāi)發(fā),代碼在服務(wù)器運(yùn)行前端三劍客超文本標(biāo)記語(yǔ)言是構(gòu)成世界的基石。 前端的發(fā)展歷程 什么是前端 前端:針對(duì)瀏覽器的開(kāi)發(fā),代碼在瀏覽器運(yùn)行 后端:針對(duì)服務(wù)器的開(kāi)發(fā),代碼在服務(wù)器運(yùn)行 前端三劍客 HTML CSS JavaScript HTML HTML(超文本標(biāo)記語(yǔ)言——HyperText Markup ...
摘要:和刷新函數(shù)是一對(duì)多的關(guān)系,即一個(gè)可以有任意多個(gè)處理它的回調(diào)函數(shù)刷新函數(shù),比如和兩個(gè)指令共用一個(gè)數(shù)據(jù)模型字段。添加數(shù)據(jù)訂閱實(shí)現(xiàn)方式為建立緩存回調(diào)函數(shù)的數(shù)組緩存回調(diào)函數(shù)當(dāng)數(shù)據(jù)模型的字段發(fā)生改變時(shí),就會(huì)觸發(fā)緩存數(shù)組中訂閱了的所有回調(diào)。 MVVM 是 Web 前端一種非常流行的開(kāi)發(fā)模式,利用 MVVM 可以使我們的代碼更專注于處理業(yè)務(wù)邏輯而不是去關(guān)心 DOM 操作。目前著名的 MVVM 框架有...
摘要:前端與狀態(tài)現(xiàn)在的前端開(kāi)發(fā)中,對(duì)于狀態(tài)的管理是重中之重。有限狀態(tài)機(jī)那么如何更好的管理前端軟件的復(fù)雜度的狀態(tài)機(jī)思想給出了自己的答案。有限狀態(tài)機(jī)并不是一個(gè)復(fù)雜的概念簡(jiǎn)單說(shuō),它有三個(gè)特征狀態(tài)總數(shù)是有限的。 前提 在現(xiàn)在的前端社區(qū),關(guān)于MVVM、Model driven view 之類的概念,已經(jīng)算是非常普及了。React/Vue 這類框架可以算是代表。而自己雖然有 React/Vue 的使用經(jīng)...
閱讀 1161·2021-11-16 11:45
閱讀 1015·2021-09-04 16:41
閱讀 3077·2019-08-29 16:40
閱讀 2852·2019-08-29 15:34
閱讀 2673·2019-08-29 13:11
閱讀 1734·2019-08-29 12:58
閱讀 1726·2019-08-28 18:00
閱讀 1775·2019-08-26 18:26