一、简介

虚拟dom是随着时代发展而诞生的产物。 命令式操作dom:

  • 简单易用
  • 程序中的状态很难管理,代码中的逻辑也很混乱。

现在三大主流框架都是声明式操作DOM。通过描述状态和DOM之间的映射关系,就可以将状态渲染成视图。状态可以是JS 中的任意类型。将状态作为输入,并生成DOM输出到页面上显示出来的过程叫渲染。 通常程序在运行时,状态会不断发生变化。状态发生变化时,就需要重新渲染。 如何确定状态中发生了什么变化以及需要在哪里更新DOM? 最简单粗暴的解决方式:把所有DOM全删了,使用状态重新生成一份DOM,输出到页面上显示出来。但是访问dom是非常昂贵的,这样会造成相当多的性能浪费。
虚拟DOM的解决方式:通过状态生成虚拟节点树,然后使用虚拟节点树进行渲染。在渲染之前,会对比新旧虚拟DOM,只渲染不同的部分。 虚拟DOM是将状态映射为视图的众多解决方案中的一种。

二、为什么VUE引入了虚拟DOM?

vue在一定程度上知道具体哪个状态发生了变化和哪些节点使用了这个状态,这样就可以通过更细粒度的绑定来更新视图。代价是粒度太细会有很多watcher同时观察某些状态,会有一些内存开销以及一些依赖追踪的开销。vue2.0采取了一个中等粒度的解决方案,状态侦测只细化到某个组件,组件内部通过虚拟DOM渲染视图,这可以大大缩减依赖数量和watcher数量。 vue通过模板描述状态和视图之间的映射关系,它会先将模板编译成渲染函数,然后执行渲染函数生成虚拟节点,使用虚拟节点更新视图。
虚拟DOM在vue中的作用:
提供虚拟节点和对比新旧vnode,并根据对比结果进行DOM操作来更新视图。

三、vnode

VNode类可以实例化不同类型的vnode实例,而不同类型的vnode实例各自表示不同类型的DOM元素。vnode可以理解为节点描述对象,描述了应该怎么创建真实DOM。

1.vnode的类型

  • 注释节点:只有两个有效属性:isComment属性和text属性
  • 文本节点:只有text属性
  • 元素节点:tag,data(节点的数据:如attrs、class、style等),children,context(当前组件的vue实例)
  • 组件节点:独有属性为componentOptions(组件节点的选项参数),componentInstance(组件实例)
  • 函数式组件:类似于组件节点,独有属性为functionalContext和functionalOptions
  • 克隆节点:将现有节点的属性复制到新节点中,与被克隆节点的唯一区别是isCloned属性,克隆节点的isCloned为true。作用是优化静态节点和插槽节点。

四、虚拟dom的核心——patch

可以将vnode渲染成真实的DOM,实际作用是计算出真正需要更新的节点,在现有DOM上进行修改来实现更新视图的目的,最大限度减少DOM操作,显著提升性能。本质是用js的运算成本替换DOM操作的执行成本,js的运算速度比DOM快得多,所以很划算。

1.patch的过程

就是以新的vnode为准增删改节点。

新增节点

  • oldVnode不存在而vnode中存在。通常发生在首次渲染中。
  • vnode和oldVnode完全不是同一个节点,vnode是新节点,而oldVnode是被废弃的节点。

删除节点

  • 节点只在oldVnode中存在。

替换过程是将新创建的DOM节点插入到旧节点的旁边,然后再将旧节点删除。

更新节点

增删节点的共同点是两个虚拟节点完全不同。新旧节点是同一个文本节点,需要进行更细致的比对。

静态节点

静态节点:一旦渲染到页面上就不会变化。 如果新旧两个虚拟节点时静态节点就直接跳过更新节点。

新虚拟节点有文本属性

新虚拟节点有文本属性而且和旧节点文本属性不一样,就直接调用setTextContent方法(在浏览器环境下是node.textContent方法)来将视图中DOM节点的内容改为虚拟节点的text属性所保存的文本。

新虚拟节点无文本属性

新虚拟节点有children:

  • 旧虚拟节点也有children属性,对新旧两个虚拟节点的children进行更详细的对比并更新(增删改移)。
  • 旧虚拟节点没有children属性,说明旧虚拟节点要么是一个空标签,要么是有文本的文本节点。如果是文本节点,先把文本清空让它变成空标签,然后将新虚拟节点(vnode)中的children挨个创建成真实的DOM元素节点并将其插入到视图中的DOM节点下面。

新虚拟节点无children:

没有text也没有children,说明是空节点。把旧虚拟节点删成空标签。

五、更新子节点的优化策略

双端对比。 只需要尝试使用相同位置的两个节点来比对是否是同一个节点:如果恰巧是同一个节点,直接就可以进入更新节点的操作;如果尝试失败了,再用循环的方式来查找节点。这样做可以很大程度地避免循环oldChildren来查找节点,从而使执行速度得到很大的提升。

  • oldChildren先循环完毕,如果newChildren中还有剩余的节点,说明这些节点都是需要新增的节点,直接把这些节点插入到DOM中就行了。
  • newChildren先循环完毕,、如果oldChildren还有剩余的节点,、说明oldChildren中剩余的节点都是被废弃的节点,是应该被删除的节点。不需要循环对比就可以知道需要将这些节点从DOM中移除。

到此这篇关于vue中的虚拟dom知识点总结的文章就介绍到这了,更多相关vue中的虚拟dom内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

vue中的虚拟dom知识点总结的更多相关文章

  1. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  2. iOS 10 Safari问题在DOM中不再包含元素

    使用此链接,您可以重现该错误.https://jsfiddle.net/pw7e2j3q/如果您点击元素并从dom中删除它,然后单击链接测试.你应该看到旧的元素弹出选择.是否有一些黑客来解决这个问题?解决方法我能够重现这个问题.问题是,每当您尝试删除其更改事件上的选择框时,iOS10都无法正确解除对选择框的绑定.要解决此问题,您需要将代码更改事件代码放在具有一些超时

  3. ios – Cordova 3.7在每个本机通话中复制iframe

    由于我已升级到Cordova3.7,每个本地调用都将一个新的iframe附加到DOM,如下所示.为了排除我现有的代码影响cordova的可能性,我尝试使用cordovaCLI创建一个新的代码,添加控制台插件,并在设备控制台中的setInterval循环中调用console.log().因此,我在DOM中收到了大量的iframe.我在iPad3,iOS7上尝试过使用xCode6构建应用程序.有没有人遇到这个问题?

  4. android – 区别:SAX Parser,XPath,DOM,XMLPullParser

    ,但Dom允许您访问xml文件的任何部分,因为它将整个文件/文档保存在内存中.看到这个article,你可以通过阅读摘要得到你想要的.另请查看此link以查看不同xml解析器的性能

  5. vue自定义加载指令v-loading占位图指令v-showimg

    这篇文章主要为大家介绍了vue自定义加载指令和v-loading占位图指令v-showimg的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  6. vue使用动画实现滚动表格效果

    这篇文章主要为大家详细介绍了vue使用动画实现滚动表格效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  7. 关于Vue 监控数组的问题

    这篇文章主要介绍了Vue 监控数组的示例,主要包括Vue 是如何追踪数据发生变化,Vue 如何更新数组以及为什么有些数组的数据变更不能被 Vue 监测到,对vue监控数组知识是面试比较常见的问题,感兴趣的朋友一起看看吧

  8. Vue子组件props从父组件接收数据并存入data

    这篇文章主要介绍了Vue子组件props从父组件接收数据并存入data的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  9. Vue h函数的使用详解

    本文主要介绍了Vue h函数的使用详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. VUE响应式原理的实现详解

    这篇文章主要为大家详细介绍了VUE响应式原理的实现,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部