vue核心之虚拟DOM
一、前言
虚拟DOM概念随着react的诞生而诞生,由facebook提出,其卓越的性能很快得到广大开发者的认可;继react之后vue2.0也在其核心引入了虚拟DOM的概念,本文将以vue2.0使用的snabbdom入手,来介绍虚拟DOM的主要实现原理。
二、虚拟DOM
在开始介绍snabbdom之前我们想来想两个问题,
(1)什么是虚拟DOM?
vdom可以看作是一个使用javascript模拟了DOM结构的树形结构,这个树结构包含整个DOM结构的信息,如下图:
(2)为什么要使用虚拟DOM?
虚拟DOM就是为了解决浏览器性能问题而被设计出来的
三、snabbdom
要了解snabbdom的话有必要先去github上先了解下snabbdom: https://github.com/snabbdom/snabbdom
在这里看到官方给的一个example
这里可以看到列出来的两个主要的核心函数,即h()函数和patch()函数,我们先来看下h()函数:
h函数
可以看到创建的虚拟DOM树里面的结构在左边的vnode里都有体现,所以现在看来我们的虚拟DOM结构树和snabbdom中的h()函数是完全可以对应起来的,可以通过一个方法将虚拟DOM结构转化成vnode;而上图中newVnode则指的是虚拟DOM树中的数据发生变化之后生成的vnode。
我们在回过头来看patch()函数
patch函数
patch函数的执行分为两个阶段,两次传递的参数都是两个
第一阶段为虚拟dom的第一次渲染,传递的两个参数分别是放真实DOM的container和生成的vnode,此时patch函数的作用是用来将初次生成的真实DOM结构挂载到指定的container上面。
第二阶段传递的两个参数分别为vnode和newVnode,此时patch函数的作用是使用diff算法对比两个参数的差异,进而更新参数变化的DOM节点;
可以发发现h函数和patch函数在cnabbdom中实现vdom到真实DOM的转化起到了至关重要的作用,那么还有一个很重要的环节,patch函数中是怎么样实现对比两个vnode从而实现对真实DOM的更新的呢,这里还要提一下snabbdom的另外一个核心算法,即diff算法。
diff算法
其实在我们日常开发中我们都在接触类似与diff算法的一些软件,比如svn可以看到当前代码和svn服务器上代码的不同之处,再如Beyond Compare这款软件也可以为我们指出两个对比文件的不同之处
但是此处是如何实现对vnode的对比的呢?参考以下代码:
1 function updateChildren(vnode, newVnode) { // 创建对比函数
2 var children = vnode.children || []
3 var newChildren = newVnode.children || []
4
5 children.forEach(function(childrenVnode, index) {
6 var newChildVnode = newChildren[index] // 首先拿到对应新的节点
7 if (childrenVnode.tag === newChildVnode.tag) { // 判断节点是否相同
8 updateChilren(childrenVnode, newChildVnode) // 如果相同执行递归,深度对比节点
9 } else {
10 repleaseNode(childrenVnode, newChildVnode) // 如果不同则将旧的节点替换成新的节点
11 }
12 })
13 }
14
15
16 function repleaseNode(vnode, newVnode) { // 节点替换函数
17 var elem = vnode.elem
18 var newEle = createElement(newVnode)
19 }
此处简单的列举了一下diff算法的原理,以上是最简单的对比,更复杂的对比函数包括对节点的增删以及其它的节点逻辑就不一一赘述了,这里最重要的一部分就是递归的使用,才能将vnode进行深度对比。
vue核心之虚拟DOM的更多相关文章
- vue中的虚拟DOM树
什么是虚拟DOM树?(Virtual DOM) 虚拟DOM树其实就是一个普通的js对象,它是用来描述一段HTML片段的 01 当页面渲染的时候Vue会创建一颗虚拟DOM树 02 ...
- 详解Vue中的虚拟DOM
摘要: 什么是虚拟DOM? 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有. 前言 Vue.js 2.0引入Virtual DOM,比Vue.js 1.0的初始渲染速度提升了2-4倍,并 ...
- Vue如何用虚拟dom进行渲染view的
前提 vue版本:v2.5.17-beta.0 触发render vue在数据更新后会自动触发view的render工作,其依赖于数据驱动:在数据驱动的工作下,每一个vue的data属性都被监听,并且 ...
- vue核心---虚拟dom的实现
生成dom的过程 由vue模板生成虚拟dom 虚拟dom转换成真实dom渲染到html页面 代码实现 要实现的真实dom <div id="box"> <p cl ...
- vue 虚拟dom
https://segmentfault.com/a/1190000008291645 一个VNode的实例对象包含了以下属性 tag: 当前节点的标签名 data: 当前节点的数据对象 VNode可 ...
- vue 的虚拟 DOM 有什么好处?
vue 中的虚拟DOM有什么好处?快! 首先了解浏览器显示网页经历的5个过程 1.解析标签,生成元素树(DOM树) 2.解析样式,生成样式树 3.生成元素与样式的关系 4.生成元素的显示坐标 5.显示 ...
- vue 快速入门 系列 —— 虚拟 DOM
其他章节请看: vue 快速入门 系列 虚拟 DOM 什么是虚拟 dom dom 是文档对象模型,以节点树的形式来表现文档. 虚拟 dom 不是真正意义上的 dom.而是一个 javascript 对 ...
- 深入理解react中的虚拟DOM、diff算法
文章结构: React中的虚拟DOM是什么? 虚拟DOM的简单实现(diff算法) 虚拟DOM的内部工作原理 React中的虚拟DOM与Vue中的虚拟DOM比较 React中的虚拟DOM是什么? ...
- vue2.0的虚拟DOM渲染
1.为什么需要虚拟DOM 前面我们从零开始写了一个简单的类Vue框架(文章链接),其中的模板解析和渲染是通过Compile函数来完成的,采用了文档碎片代替了直接对页面中DOM元素的操作,在完成数据的更 ...
随机推荐
- linux服务器的所有服务web/dns/dhcp/vsftp-nfs-samba的配置
nfs是sun开发的 network filesystem 网络文件系统,相当于win的映射网络驱动器, 可以将一台nfs服务器上的目录"挂载"到本地机器上的 一个 本地目录 一样 ...
- Android中EditText焦点问题
https://www.jianshu.com/p/3d31d681f4bc 问题:当EditText失去焦点时做内容校验 场景:用户编辑EditText将内容清空,当点击空白地方时关闭软键盘,同时校 ...
- p3302 [SDOI2013]森林(树上主席树+启发式合并)
对着题目yy了一天加上看了一中午题解,终于搞明白了我太弱了 连边就是合并线段树,把小的集合合并到大的上,可以保证规模至少增加一半,复杂度可以是\(O(logn)\) 合并的时候暴力dfs修改倍增数组和 ...
- 正则匹配-URL-域名
DNS规定,域名中的标号都由英文字母和数字组成,每一个标号不超过63个字符,也不区分大小写字母.标号中除连字符(-)外不能使用其他的标点符号.级别最低的域名写在最左边,而级别最高的域名写在最右边.由多 ...
- 「BZOJ2153」设计铁路 - 斜率DP
A省有一条东西向的公路经常堵车,为解决这一问题,省政府对此展开了调查. 调查后得知,这条公路两侧有很多村落,每个村落里都住着很多个信仰c教的教徒,每周日都会开着自家的车沿公路到B地去"膜拜& ...
- URL简单梳理
# DEBUG模式: 开启debug模式后,修改项目代码时按下ctrl+s可重启项目: 项目中出现bug时,浏览器与控制台会打印错误信息: 在生产环境中禁止开启DEBUG模式,有很大的安全隐患: 将D ...
- 用命令bat打开某个文件或文件夹
打开文件或文件夹可以用start命令,start命令会根据文件关联的程序自动调用关联的程序打开文件和文件夹. 可以用记事本写如下命令,之后改扩展名为.bat即可 打开文件夹 start "& ...
- mybatis+spring boot, mapper 提示Could not autowire. No beans of … type found
工具及背景: IntelliJ IDEA 2016.1.3 Ultimate.spring boot, maven项目,利用mybatis 注解的方式查询mysql. 业务逻辑关系:controlle ...
- python 操作记事本
需事先打开记事本,再运行下面脚本 # encoding: utf- import win32api import win32gui import win32con print("Hello, ...
- ppython的移位操作
因为要将js的一个签名算法移植到python上,遇到一些麻烦. int无限宽度,不会溢出 算法中需要用到了32位int的溢出来参与运算,但是python的int是不会溢出的,达到界限后会自己转为lon ...