从 jquery 的操作 dom 到 vue,react等框架的vdom实现,大大减少了dom的操作,提高性能。前端的刀耕火种,到现在的模块化,前端的内容每天都在发生着变化,每天都有着进步。前端的发展中我们绕不过一个坎,那就是jquery,接下来我们会对比jquery和现在框架,来发现这些年前端取得的进步。
jquery与框架的区别:
jquery的本质还是操作dom,在处理dom的时候,也会导致数据和视图层的不分离,数据中有dom的操作。这是jquery淘汰的一个原因,因为他不符合基本的开闭原则(对修改关闭,对扩展开放)。
现在为我们熟知的框架,则是很好处理了这个问题。实现了数据和视图的分离,解耦了视图层和数据层,通过中间层来达到控制的目的,以数据驱动视图,只关心数据的变化,DOM的操作被封装。
理解MVVM:
提到MVVM不得不提他的老前辈MVC(Model + View + Controller)
MVC:原型+视图+控制器。用户通过操作视图。进而控制器去改变原型,进而改变视图显示。又或者用户直接操作控制器改变原型,进而改变视图层的显示。jquer就是基于此设计的
在MVC的基础上,前端创新的MVVM的VM(View Model),介于View层和Model层中间的VM层。他起着桥梁的作用。
视图层通过事件来绑定模型层(数据层),数据层通过数据绑定来改变视图层。VM就起着衔接的作用。我们就可以实现只关心数据的变化,不用去用控制器操作。
MVVM框架的三大要素:响应式,模板引擎,渲染
响应式:vue如何监听data的变化?
模板引擎:vue的模板如何被解析,指令如何变化
渲染:vue的模板如何被渲染成html?以及渲染过程
响应式:
这里的响应式是数据的响应式,数据的变化会被实时监听。而vue实现data数据实时监听的核心函数是Object.defineProperty
这是es5中对象上的方法,他能实现对对象属性get和set的监听。
//响应式数据的核心函数,监听数据改变
var vm = {};
var obj = {
name: "xb",
age: 18,
// like
};
var key;
for (key in obj) {
(function(key) {
Object.defineProperty(vm, key, {
get: function() {
console.log("get", obj[key]); //监听
return obj[key];
},
set: function(newVal) {
console.log("set", newVal); //监听
obj[key] = newVal
}
});
})(key);
}
这里我们还可以提出一个问题,就是data中的数据如何挂载到Vue实例上去的,其实也就是这个方法。在Vue3.0版本以后,实现对数据的监听换成了新的方法,运用了es6的语法(这里不扩展)。
模板引擎:
模板是什么:在vue中,是字符串,他有逻辑,还嵌入了JS变量。本质其实就是字符串。逻辑对应的就是v-if,v-for等。他与html很像,但是区别很大,html是静态的,html中没有逻辑,没有JS变量。所以他可以按照浏览器指定好的规则去渲染,但是vue模板不能。他必须先解析。转化为html,才能渲染到页面。
这里提到的解析,应该就知道我们需要借用JS了,因为JS是前端中图灵完备的语言。(https://blog.csdn.net/robinsone/article/details/39004057)
因此,模板最重要是转换成一个JS函数,在由JS转化成html(这里指的是render函数(泛指渲染函数))
render函数执行完会返回一个vnode(虚拟节点)
这里我们就要提到前面的vdom(虚拟dom)。
vdom:
提问;vdom是什么,为什么会存在。vdom如何应用,核心API是什么,
什么是vdom和为什么会存在:
用JS模拟dom结构,dom变化的对比放在JS层来做,存在的原因是提高重绘性能。
再次提出问题:为什么dom操作是‘昂贵’的。
我们创建一个dom元素。然后遍历这个dom元素,你会发现dom元素上有很多很多属性。
最主要的原因还是,每次操作dom,会调用cpu和gpu。页面的重排占用cpu的计算能力,页面的重绘占用了gup的图像处理能力。
这里还要说下gpu的分类。分为家用的和专业的。家用显卡也被称为游戏显卡。游戏显卡他擅长于做贴图,光影这些东西。专业显卡,擅长于画图,专业显卡的性能要比家用显卡好上几十倍。
我们每次页面的重排重绘都是相当于画图,而我们绝大部分的显卡都是家用显卡,所以在画图这方面性能并不好。
所以追寻到问题的本质,就是硬件的问题,导致操作dom显得那么‘昂贵’。
明白了操作dom为什么是‘昂贵’的,就明白了vdom为什么会存在。
vdom的应用:
介绍的是snabbdom
核心API:h函数和patch函数
h函数:定义一个dom节点——vnode(模拟dom节点)
patch函数:接收两个参数。初始的cantainer,和vnode
patch(container,vnode)//初次渲染
patch(vnode,newVnode) //再次渲染
patch函数就是一个对比函数,这里涉及到了diff算法。(不是新东西。早在git命令中就有,对比两个文本的差别)
vdom为何用diff算法:
dom的操作是‘昂贵’的,算法的目的找出本次dom必须更新的节点来更新,其他节点不更新。这个过程就叫diff算法。
render函数:
模板的所有信息都包含在render函数中
函数执行完返回一个vnode(模拟节点)
vue整个流程:四部曲
解析模板成render函数
响应式开始监听
首次渲染,显示页面,且绑定依赖
data属性变化,触发rerender函数(二次渲染)