一、前言

虚拟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的更多相关文章

  1. vue中的虚拟DOM树

    什么是虚拟DOM树?(Virtual DOM)   虚拟DOM树其实就是一个普通的js对象,它是用来描述一段HTML片段的    01    当页面渲染的时候Vue会创建一颗虚拟DOM树 02    ...

  2. 详解Vue中的虚拟DOM

    摘要: 什么是虚拟DOM? 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有. 前言 Vue.js 2.0引入Virtual DOM,比Vue.js 1.0的初始渲染速度提升了2-4倍,并 ...

  3. Vue如何用虚拟dom进行渲染view的

    前提 vue版本:v2.5.17-beta.0 触发render vue在数据更新后会自动触发view的render工作,其依赖于数据驱动:在数据驱动的工作下,每一个vue的data属性都被监听,并且 ...

  4. vue核心---虚拟dom的实现

    生成dom的过程 由vue模板生成虚拟dom 虚拟dom转换成真实dom渲染到html页面 代码实现 要实现的真实dom <div id="box"> <p cl ...

  5. vue 虚拟dom

    https://segmentfault.com/a/1190000008291645 一个VNode的实例对象包含了以下属性 tag: 当前节点的标签名 data: 当前节点的数据对象 VNode可 ...

  6. vue 的虚拟 DOM 有什么好处?

    vue 中的虚拟DOM有什么好处?快! 首先了解浏览器显示网页经历的5个过程 1.解析标签,生成元素树(DOM树) 2.解析样式,生成样式树 3.生成元素与样式的关系 4.生成元素的显示坐标 5.显示 ...

  7. vue 快速入门 系列 —— 虚拟 DOM

    其他章节请看: vue 快速入门 系列 虚拟 DOM 什么是虚拟 dom dom 是文档对象模型,以节点树的形式来表现文档. 虚拟 dom 不是真正意义上的 dom.而是一个 javascript 对 ...

  8. 深入理解react中的虚拟DOM、diff算法

    文章结构: React中的虚拟DOM是什么? 虚拟DOM的简单实现(diff算法) 虚拟DOM的内部工作原理 React中的虚拟DOM与Vue中的虚拟DOM比较 React中的虚拟DOM是什么?   ...

  9. vue2.0的虚拟DOM渲染

    1.为什么需要虚拟DOM 前面我们从零开始写了一个简单的类Vue框架(文章链接),其中的模板解析和渲染是通过Compile函数来完成的,采用了文档碎片代替了直接对页面中DOM元素的操作,在完成数据的更 ...

随机推荐

  1. POJ1741 Tree(树分治——点分治)题解

    题意:给一棵树,问你最多能找到几个组合(u,v),使得两点距离不超过k. 思路:点分治,复杂度O(nlogn*logn).看了半天还是有点模糊. 显然,所有满足要求的组合,连接这两个点,他们必然经过他 ...

  2. CodeTyphon跨平台交叉编译的配置

    CodeTyphon和Lazarus的关系相当于就是ubuntu和linux的关系 不过CodeTyphon提供了很多一键配置即可使用的交叉编译配置,而Lazarus就比较麻烦了,我也没用Lazaru ...

  3. P3311 [SDOI2014]数数

    思路 看到多个子串并且不能包含的情况,想到了AC自动机 但是题目多了一个不能大于给出的n的限制条件,联想数位dp的过程,设f[i][j][0/1]表示在第i位,AC自动机的第j个节点,数位有/无限制的 ...

  4. Summary on Visual Tracking: Paper List, Benchmarks and Top Groups

    Summary on Visual Tracking: Paper List, Benchmarks and Top Groups 2018-07-26 10:32:15 This blog is c ...

  5. POJ 2718 Smallest Difference(最小差)

     Smallest Difference(最小差) Time Limit: 1000MS    Memory Limit: 65536K Description - 题目描述 Given a numb ...

  6. Go 字典(Map)

    比较熟悉 Python 的对于字典肯定不会陌生,在 Go 中 map 就是 Python 中字典的概念,它的基本格式是 map[keyType]valueType .map 的读取和设置和 slice ...

  7. java虚拟机知识和 内存 堆(heap)、栈(stack)和方法区(method)

    1.虚拟机实例 每个java程序都运行在自己的java虚拟机实例中,运行三个java程序就会得到三个虚拟机实例 守护线程(虚拟机自己使用,比如说执行垃圾收集任务的线程) 非守护线程(java初试线程, ...

  8. 给 layui upload 带每个文件的进度条, .net 后台代码

    1.upload.js 扩展 功能利用ajax的xhr属性实现该功能修改过modules中的upload.js文件功能具体实现:在js文件中添加监听函数 //创建监听函数 var xhrOnProgr ...

  9. git pull 提示 There is no tracking information for the current branch

    在执行git pull的时候,提示当前branch没有跟踪信息: git pull There is no tracking information for the current branch. P ...

  10. 【Selenium2】【selenium之 定位以及切换frame(iframe)】

    参考:http://blog.csdn.net/huilan_same/article/details/52200586 总有人看不明白,以防万一,先在开头大写加粗说明一下: frameset不用切, ...