一、 前言
虚拟DOM概念随着React的诞生而诞生,由facebook提出,其卓越的性能很快得到广大开发者的认可;继React以后Vue2.0也在其核心引入了虚拟DOM的概念,本文将深入Vue源码,来介绍虚拟DOM的主要实现原理。
二、 DOM和虚拟DOM区别
DOM的本质:
浏览器概念,浏览器从服务器端读取html页面,浏览器将html解析成一棵元素嵌套关系的dom树,用对象来表示页面上的元素,并提供操作dom对象的api。
虚拟DOM:
框架概念,程序员用js对象来模拟页面上dom元素的嵌套关系( 本质 ),为了实现页面元素的高效更新( 目的 )
三、Vue中的虚拟DOM
DOM是很慢的,其元素非常庞大,页面的性能问题鲜有由JS引起的,大部分都是由DOM操作引起的。而虚拟的
DOM的核心思想是:对复杂的文档DOM结构,提供一种方便的工具,进行最小化地DOM操作。
目标:
i) 怎么将真正的DOM转换为虚拟DOM
ii) 怎么将虚拟 DOM 转换为 真正的 DOM
将真正的DOM转化为虚拟DOM:
这里我们创建VNode方便我们后面使用,在它的是构造函数中传递我们需要的数据,这里就不多说了,下面来看下我们将DOM转换的方法:
这里我们通过检测我们传入的元素的root的nodeType进行一个区分,1,3分别为元素节点,和文本节点 。在1的时候获取到我们标签中的属性节点,将他存入_attrobj中,最后将需要的参数存到我们New的VNode中以实现我们DOM的转换,这里有关于递归的一些操作,如果有不知道的同学去看一下我们往期的文章或者去网上搜集一些有关递归的相关知识。
将虚拟的DOM转化为真正的DOM:
将虚拟DOM转换为真实的DOM思路一样这里就不一一列举了。
上面的案例为了方便同学们进行理解对Vue中的虚拟DOM进行了简化,真实 的Vue中使用 HTML 的字符串作为模板, 将字符串的 模板 转换为 AST, 再转换为 虚拟DOM。
虚拟DOM中的render方法:
Render的作用是将虚拟DOM转换为真正的DOM加载到页面中,前面我们说过了DOM的转换,下面我们来看一下render是怎么渲染的呢
这里通过函数柯里化在mount中的render中进行DOM转换,在真正的Vue中使用了二次提交的设计架构:在页面中的DOM和虚拟DOM是一一对应的关系,先有AST抽象语法树和数据生成虚拟DOM(新,render),将现有的虚拟DOM和新的虚拟DOM继续比较(DIFF算法进行比较)更新。
• 虚拟DOM可以降级理解为AST
• 一个项目运行的时候 模板是不会变得,就表示AST是不会变得,我们可以将代码进行优化,将虚拟DOM缓存起来,生成一个函数,函数只要传入数据 就可以得到真正的DOM
四、函数柯里化
我们刚刚分析Vue源码,遇见好几次函数柯里化,这里对函数柯里化做一个讲解:
下面我们来看一道面试题:
我们用函数柯里化对其进行解答:
我们来分析一下这个add函数,我们在第一次执行的时候定义一个数组专门用来存储所有的参数,然后我们在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值并将他赋值给_adder,利用toString隐式转换的特性,当最后执行时隐式转换,并计算出最后的结果。
五、总结
• 毋庸置疑虚拟 DOM 带给前端的意义是非凡的,虚拟 DOM 在现如今还有更多新鲜的玩法。
• 比如 omi 将虚拟 DOM 与 Web Component 的结合,还有 Taro 和 Chameleon 带来的多端统一的能力。