MVC&MVVM
双向绑定原理
观察者模式
虚拟DOM
(此文章用来先占坑,后面会更新详细一些)
MVC&MVVM
先看这样一张图
MVC的思想:一句话描述就是controller负责将model的数据用view显示出来
但是这样有一些问题就是:
1.开发者需要大量调用相同的DOM API,操作冗余,代码难以维护
2.降低页面渲染性能,
3.当Model层变化,开发者需要主动更新到view,当用户页面操作导致数据发生变化,开发者也需要同步到model中。
而MVVM 出现了,它的核心思想就是通过双向数据绑定原理把view层和model层连接起来,它俩之间的数据同步工作完全是自动的,无需人为干涉,因此开发者只需要关注业务逻辑,不需要手动操作DOM,不需要关注数据状态的同步问题,复杂的数据状态维护全部由MVVM统一管理。
区别:
MVC也是一种设计思想,主要就是MVC中的Controlled演变成MVVM中的ViewModel。MVVM主要解决了MVC中大量的DOM操作使页面渲染性能降低,加载速度变慢,影响用户体验。和当Model频繁发送变化,开发者需要主动更新到View。
双向数据绑定原理
利用Object.defineProperty()对数据进行劫持,设置一个监听器Observer,用来监听所有属性,如果属性上发生变化了,就需要告诉订阅者Watcher去更新数据,最后指令解析器Compile解析对应的指令,进而会执行对应的更新函数,从而更新视图,实现双向绑定。
观察者模式(Observer)
观察者模式又被称为发布-订阅者模式或消息机制,它定义了对象间的一对多的依赖关系,只要一个对象的状态改变时,所有依赖于它的对象都得到通知并被自动更新,解决了主体对象与观察者之间功能的耦合。
平常对DOM的事件绑定就是一个非常典型的发布-订阅者模式,我们需要监听用户点击按钮这个动作,所以订阅按钮上的click
事件,只要按钮被点击,就会向订阅者发布这个消息,然后做相应操作。
大致的结构是这样
const Observer = (function(){
let _message = {};
return {
//注册消息
on: function(){},
//发布消息
subscribe: function(){},
//移除消息
off: function (){},
}
})();
这个模式的使用场景就是当一个对象的改变需要改变其他对象,并且不知道有多少对象需要改变的时候。
使用它的好处有:
1.支持简单的广播通信,自动通知所有已经订阅过的对象
2.页面载入后目标对象很容易与观察者对象存在一种动态关联,增加灵活性
3.目标对象和观察者对象之间的抽象耦合关系能够单独扩展和重用
填充一下
const Observer = (function(){
let _message = {};
return {
//注册消息,参数是被注册的消息类型,绑定的事件
//可对同一个对象多次调用这个方法
on: function(type,fn){
if(typeof _message[type] === 'undefined'){
_message[type] = [fn];
}else{
_message[type].push(fn);
}
},
//发布消息,参数是类型,和上一步的fn需要被传递的参数
subscribe: function(type,args){
if(!_message[type]) return;
let events = {
type: type,
args: args || {},
};
let length = _message[type].length;
for(let i=0; i<length ; i++){
_message[type][i].call(this,events);
}
},
//移除消息,与注册消息对应
off: function (type,fn){
if(_message[type]){
let ind = _message[type].indexOf(fn) ;
ind >-1 && _message[type].splice(ind,1);
}
},
}
})();
虚拟DOM
因为原本的浏览器渲染在页面发生变化时会频繁操作DOM来显示对应的修改,这样会产生性能问题,也会影响用户体验,虚拟DOM的思想就是将页面要更新的节点信息先全部保存到本地一个js对象中,最后再将这个js对象一次性加入到DOM树中,再进行后续操作,避免大量无谓的计算量。
diff算法
主要是对新旧两棵树进行深度遍历,每个节点都有一个标记,每遍历到一个节点就把该节点与新的树做对比,有差异就记录到一个对象中。
平层比较两棵树时会有四种情况:
1.节点类型变了(REPLACE
)
2.节点类型一样,仅仅属性或属性值变了(PROPS
)
3.文本变了(TEXT
)
4.插入删除增加节点(REORDER
)
最后根据得到的这样的一个diff算法结果表,更新DOM
响应式布局
概念:
为了实现不同屏幕分辨率的终端上浏览网页的不同展示方式,兼容多个终端,提高用户体验。
设计步骤(主要就是在完成非响应式布局后,再修改成响应式布局):
1.设置meta,
2.通过媒体查询(media query
)设置样式
3.设置多种视图宽度
4.设置字体