vue中的虚拟dom知识点总结

目录
  • 一、简介
  • 二、为什么VUE引入了虚拟DOM?
  • 三、vnode
    • 1.vnode的类型
  • 四、虚拟dom的核心——patch
    • 1.patch的过程
      • 新增节点
      • 删除节点
      • 更新节点
      • 静态节点
      • 新虚拟节点有文本属性
      • 新虚拟节点无文本属性
  • 五、更新子节点的优化策略

一、简介

虚拟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内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue 虚拟DOM的原理

    为什么需要虚拟DOM? 如果对前端工作进行抽象的话,主要就是维护状态和更新视图,而更新视图和维护状态都需要DOM操作.其实近年来,前端的框架主要发展方向就是解放DOM操作的复杂性. 运行js的速度是很快的,大量的操作DOM就会很慢,时常在更新数据后会重新渲染页面,这样造成在没有改变数据的地方也重新渲染了DOM 节点,这样就造成了很大程度上的资源浪费. 在jQuery出现以前,我们直接操作DOM结构,这种方法复杂度高,兼容性也较差.有了jQuery强大的选择器以及高度封装的API,我们可以更方便的

  • Vue源码分析之虚拟DOM详解

    为什么需要虚拟dom? 虚拟DOM就是为了解决浏览器性能问题而被设计出来的.例如,若一次操作中有10次更新DOM的动作,虚拟DOM不会立即操作DOM,而是将这10次更新的diff内容保存到本地一个JS对象中,最终将这个JS对象一次性attch到DOM树上,再进行后续操作,避免大量无谓的计算量.简单来说,可以把Virtual DOM 理解为一个简单的JS对象,并且最少包含标签名( tag).属性(attrs)和子元素对象( children)三个属性. ----- 元素节点: 元素节点更贴近于我们

  • 关于Vue虚拟dom问题

    一.什么是虚拟dom? 虚拟dom本质上就是一个普通的JS对象,用于描述视图的界面结构 在vue中,每个组件都有一个render函数, 没有render找template,没有template找el,有el就会把el.outHTML作为template,然后把这串字符串编译成render函数. 有template就不往下找了.有render同理. 每个render 函数都会返回一个虚拟dom树,这也就意味着每个组件都对应一棵虚拟DOM树. 也就是说render目的就是创建虚拟dom,这个组件到底

  • vue 虚拟DOM快速入门

    虚拟 DOM 什么是虚拟 dom dom 是文档对象模型,以节点树的形式来表现文档. 虚拟 dom 不是真正意义上的 dom.而是一个 javascript 对象. 正常的 dom 节点在 html 中是这样表示: <div class='testId'> <p>你好</p> <p>欢迎光临</p> </div> 而在虚拟 dom 中大概是这样: { tag: 'div', attributes:{ class: ['testId']

  • 一篇文章带你搞懂Vue虚拟Dom与diff算法

    前言 使用过Vue和React的小伙伴肯定对虚拟Dom和diff算法很熟悉,它扮演着很重要的角色.由于小编接触Vue比较多,React只是浅学,所以本篇主要针对Vue来展开介绍,带你一步一步搞懂它. 虚拟DOM 什么是虚拟DOM? 虚拟DOM(Virtual   Dom),也就是我们常说的虚拟节点,是用JS对象来模拟真实DOM中的节点,该对象包含了真实DOM的结构及其属性,用于对比虚拟DOM和真实DOM的差异,从而进行局部渲染来达到优化性能的目的. 真实的元素节点: <div id="wr

  • vue中对虚拟dom的理解知识点总结

    本质是一个普通的js对象,用于描述视图界面结构的, 在mouted的回调中,可以输出_vnode, 通过图可以知道,_vnode中有以下几个主要的属性: tag:组件的标签名, data: 组件的属性, children: 组件的子标签 parent: 父级元素 render函数: 作用:创建虚拟dom, 每个组件都有虚拟dom,并且虚拟dom都是由render函数创建的: 使用虚拟dom树的目的:提高渲染效率 在vue中,当渲染视图时候会调用render函数.这种渲染不仅发生在组件创建时候,还

  • Vue虚拟Dom到真实Dom的转换

    再有一颗树形结构的Javascript对象后, 我们需要做的就是讲这棵树跟真实Dom树形成映射关系.我们先回顾之前的mountComponnet 方法: export function mountComponent(vm, el) { vm.$el = el ... callHook(vm, 'beforeMount') ... const updateComponent = function () { vm._update(vm._render()) } ... } 我们已经执行完了vm._r

  • vue中的虚拟dom知识点总结

    目录 一.简介 二.为什么VUE引入了虚拟DOM? 三.vnode 1.vnode的类型 四.虚拟dom的核心——patch 1.patch的过程 新增节点 删除节点 更新节点 静态节点 新虚拟节点有文本属性 新虚拟节点无文本属性 五.更新子节点的优化策略 一.简介 虚拟dom是随着时代发展而诞生的产物. 命令式操作dom: 简单易用 程序中的状态很难管理,代码中的逻辑也很混乱. 现在三大主流框架都是声明式操作DOM.通过描述状态和DOM之间的映射关系,就可以将状态渲染成视图.状态可以是JS 中

  • react中的虚拟dom和diff算法详解

    虚拟DOM的作用 首先我们要知道虚拟dom的出现是为了解决什么问题的,他解决我们平时频繁的直接操作DOM效率低下的问题.那么为什么我们直接操作DOM效率会低下呢? 比如我们创建一个div,我们可以在控制台查看一下这个div上自带或者继承了很多属性,尤其是我们使用js操作DOM的时候,我们的DOM本身就很复杂,js的操作也会占用很多时间,但是我们控制不了DOM元素本身,因此虚拟DOM解决的是js操作DOM这一层面,其实解决的是减少了操作dom的次数 简单实现虚拟DOM 虚拟DOM,见名知意,就是假

  • Vue中简单的虚拟DOM是什么样

    目录 1. 一个简单的虚拟DOM长什么样 2. Vue中的虚拟DOM长什么样 3. Vue中的虚拟DOM实现 4. createTextVNode 1. 一个简单的虚拟DOM长什么样 其实当今前端框架不少用到了虚拟DOM的技术,但各家有各家的实现.这里我们先看下比较简单的虚拟DOM库snabbdom的虚拟DOM长什么样 我们假设有html如下,其实也就是所谓的真实DOM <div class="message">Hello World</div> 那么snabb

  • vue2.0的虚拟DOM渲染思路分析

    1.为什么需要虚拟DOM 前面我们从零开始写了一个简单的类Vue框架(文章链接),其中的模板解析和渲染是通过Compile函数来完成的,采用了文档碎片代替了直接对页面中DOM元素的操作,在完成数据的更改后通过appendChild函数将真实的DOM插入到页面. 虽然采用的是文档碎片,但是操作的还是真实的DOM. 而我们知道操作DOM的代价是昂贵的,所以vue2.0采用了虚拟DOM来代替对真实DOM的操作,最后通过某种机制来完成对真实DOM的更新,渲染视图. 所谓的虚拟DOM,其实就是 用JS来模

  • Vue中key的作用及原理详解

    目录 1. 先说结论 2. key的作用 2.1 举一个例子 2.2 修改一下上述示例 2.3 再修改一下示例 3. key的实现原理 1. key为index的情况. 2. key为id的情况. 总结 1. 先说结论 key在Vue是DOM对象的标识: 进行列表展示时,默认key是index: 如果数据只做展示使用,使用index作为key是没有任何问题的: 如果使用index作为key,而后续操作会破坏顺序,一定会带来效率问题,严重时会渲染出错误的DOM 关于key的作用及实现原理,下面一一

  • Vue 中为什么不推荐用index 做 key属性值

    目录 前言 key 的作用 key 在 diff 算法中的角色 同步头部节点 同步尾部节点 添加新的节点 删除多余节点 最长递增子序列 为什么不要用 index 性能消耗 数据错位 解决方案 总结 前言 前端开发中,只要涉及到列表渲染,那么无论是 React 还是 Vue 框架,都会提示或要求每个列表项使用唯一的 key,那很多开发者就会直接使用数组的 index 作为 key 的值,而并不知道 key 的原理.那么这篇文章就会讲解 key 的作用以及为什么最好不要使用 index 作为 key

  • Vue3 如何通过虚拟DOM更新页面详解

    目录 引言 Vue 虚拟 DOM 执行流程 DOM 的创建 patch 函数 patchElement 函数 节点自身属性的更新 子元素的更新 patchChildren 位运算 为什么位运算性能更好 如何运用位运算 最长递增子系列 贪心 + 二分 引言 上一讲我们主要介绍了 Vue 项目的首次渲染流程,在 mountComponent 中注册了effect 函数,这样,在组件数据有更新的时候,就会通知到组件的 update 方法进行更新 Vue 中组件更新的方式也是使用了响应式 + 虚拟 DO

随机推荐