摘要:原来是在改变数据时,还要手动。现在只需要直接改变数据,会自动,更新元素。参考资料现代前端技术解析,张成文,年月第版,和的图示,阮一峰,年月日,
author: 陈家宾 email: 617822642@qq.com date: 2018/3/1MVVM 背景
都说懒惰使人进步,MVVM 的进化史,正印证了这句话,是一步步让开发人员更懒惰更简单的历史:
直接 DOM 操作 -> MVC -> MVP -> MVVM
最开始的前端交互,是很直接的 DOM 操作,最出名的这类库当数 jQuery 了,封装了 DOM API,让一切 DOM 操作都变得简单。
但当页面数据和交互多的时候,散乱的代码将使项目变得难以维护,让人发狂。所以才有了 MV* 模式的发展。
MV* 模式MVC & MVP & MVVM 三者对比伪代码:点我MVC
Model:数据模型 & 手动渲染模板
View:模板
Controller:修改数据
MVPModel:数据模型
View:模板
Presenter:修改数据 & 手动渲染模板
MVP 是 MVC 模式的一种改造(这里不说改进,是因为两者其实很相似,没有本质上的变化),将 手动渲染 步骤** 从 Model 移到了 Presenter,让 View 和 Model 更独立更存粹了,但从另一个角度来说,也加大了 Presenter 的工作。
MVVMModel:数据模型
View:带特殊属性的 html 模板
ViewModel:依靠 Directive,修改数据 & 自动渲染
MVVM 模式依靠 Directive,实现了 模板自动渲染,极大地解放了开发者的双手,此时开发者只需关注 View 和 Model,效率和可维护性方面达到了飞跃式的进步。
下面将着重介绍下神奇的 Directive。
数据变更检测方案(Directive) (一)手动触发绑定在页面需要改变时,手动触发检测,改变 model 数据,并扫描元素,对有特殊标记的元素进行修改
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]); } } } }(二)脏检测机制
针对手动绑定进行优化,只对修改到的数据进行更新元素
function scan(elems, val) { let list = document.querySelectorAll(`[v-bind=${val}]`); // 只扫描修改到的数据涉及的元素 for (let elem of elems) { for (let attr of elem.attributes) { let dataKey = elem.getAttribute("v-bind"); if (elem.directive[attr.nodeValue] !== data[dataKey]) { // 当元素值有变时,更新元素 directive[attr.nodeValue].call(elem, data[dataKey]); elem.directive[attr.nodeValue] = data[dataKey]; // 保存元素当前值 } } } }(三)前端数据对象劫持(Hijacking)
在上面的基础更进一步,使用 Object.defineProperty 对数据进行 get & set 监听,当数据有变时,自动执行 scan 扫描并更新元素。
原来是在改变数据时,还要手动 scan。现在只需要直接改变数据,会自动 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
与方法三类似,换了种写法,这里应用了 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]; } });
以上。
参考资料《现代前端 技术解析》,张成文,2017 年 4 月第 1 版d
《MVC,MVP 和 MVVM 的图示》,阮一峰,2015年2月 1日,http://www.ruanyifeng.com/blo...
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/93034.html
摘要:小白一枚,一直使用的是,想要多了解一些其它的框架,正好最近越来越火热,上的数已经超过了。框架理解说起这个模型,就不得不说框架。函数表示创建一个文本节点,函数表示创建一个数组。 小白一枚,一直使用的是React,想要多了解一些其它的框架,正好最近Vue越来越火热,Github上的Star数已经超过了React。而其背后蕴含的MVVM框架思想也一直跟React的组件化开发思想并驾齐驱,在这...
摘要:和刷新函数是一对多的关系,即一个可以有任意多个处理它的回调函数刷新函数,比如和两个指令共用一个数据模型字段。添加数据订阅实现方式为建立缓存回调函数的数组缓存回调函数当数据模型的字段发生改变时,就会触发缓存数组中订阅了的所有回调。 MVVM 是 Web 前端一种非常流行的开发模式,利用 MVVM 可以使我们的代码更专注于处理业务逻辑而不是去关心 DOM 操作。目前著名的 MVVM 框架有...
摘要:前端与状态现在的前端开发中,对于状态的管理是重中之重。有限状态机那么如何更好的管理前端软件的复杂度的状态机思想给出了自己的答案。有限状态机并不是一个复杂的概念简单说,它有三个特征状态总数是有限的。 前提 在现在的前端社区,关于MVVM、Model driven view 之类的概念,已经算是非常普及了。React/Vue 这类框架可以算是代表。而自己虽然有 React/Vue 的使用经...
阅读 1160·2021-11-16 11:45
阅读 1014·2021-09-04 16:41
阅读 3076·2019-08-29 16:40
阅读 2851·2019-08-29 15:34
阅读 2672·2019-08-29 13:11
阅读 1734·2019-08-29 12:58
阅读 1725·2019-08-28 18:00
阅读 1775·2019-08-26 18:26