关于Vue虚拟dom问题

一、什么是虚拟dom?

虚拟dom本质上就是一个普通的JS对象,用于描述视图的界面结构

在vue中,每个组件都有一个render函数,

没有render找template,没有template找el,有el就会把el.outHTML作为template,然后把这串字符串编译成render函数。
有template就不往下找了。有render同理。

每个render 函数都会返回一个虚拟dom树,这也就意味着每个组件都对应一棵虚拟DOM树。
也就是说render目的就是创建虚拟dom,这个组件到底要显示啥。
console.log(‘render'); ↓


题外:console.dir()可以显示一个对象所有的属性和方法。

如果没有return,这时候在页面中是不存在真实dom的。
加上return↓

h函数名字是自定义的,h函数结构,h(标签,{自身属性},[子元素])
子元素继续用h函数建,因为有别的属性
我们在[ ]里面再创建一个子元素

h函数做了判断,如果不是对象,就是文本节点了,↑认为是省略掉了中间的配置

在页面内渲染出来。
console.log(vnode);

h1子元素↓


通过.elm对应真实结点

h(‘h1','{{title}}')这种是肯定不行的,必须h(‘h1',this.title)

二、为什么需要虚拟dom

在vue 中,渲染视图会调用render 函数,这种渲染不仅发生在组件创建时,同时发生在视图依赖的数据更新时。如果在渲染时,直接使用真实 DOM ,由于真实DOM的创建、更新、插入等操作会带来大量的性能损耗,从而就会极大的降低渲染效率。
因此, vue 在渲染时,使用虚拟dom来替代真实dom,主要为解决渲染效率的问题。

生成真实dom在第一次加载的时候没有任何问题,因为无法避免,必要要生成真实dom。
render函数不止生成一次,它是每一次数据变化都要生成。
但是如果在render里用createElement每次都会生成全新的dom元素,开销太大了

三、虚拟dom是如何转换为真实dom的

在一个组件实例首次被渲染时,它先生成虚拟dom树,深度优先遍历结点,setAttribute,然后根据虚拟dom树创建真实dom,并把真实dom挂载到页面中合适的位置,直接替换掉div#app,此时,每个虚拟dom便会对应一个真实的dom。

是不等于的,因为直接替换掉了div#app

如果一个组件受响应式数据变化的影响,需要重新渲染时,它仍然会重新调用render函数,创建出一个新的虚拟dom树,用新树和旧树对比,通过对比,vue会找到最小更新量,然后更新必要的真实dom节点
这样一来,就保证了对真实dom达到最小的改动。

通过diff算法查看那两个虚拟dom是不一样的,然后去改动对应结点的真实dom完成效果,保证改动最少,提高效率

四、模板和虚拟dom的关系

脚手架搭的虚拟dom

vue框架中有一个compile模块,它主要负责将模板转换为render函数,而render函数调用后将得到虚拟dom。

编译的过程分两步,(babel和webpack都是这么创建的):

将模板字符串转换成为AST(抽象语法树,用树形结构描述我们的东西)将AST转换为render函数

AST↓,提一嘴AST用栈搭建的

如果使用传统的引入方式(src),则编译时间发生在组件第一次加载时,这称之为运行时编译。再提一嘴,第1步非常耗时。
如果是在vue-cli的默认配置下,编译发生在打包时,这称之为模板预编译。
编译是一个极其耗费性能的操作,预编译可以有效的提高运行时的性能,而且,由于运行的时候已不需要编译,vue-cli在打包时会排除掉vue中的compile模块,以减少打包体积

如果上面不写模板template


会报错,但是你可以在vue.config.js配置

module.export={runtimeCompiler:true}

不建议,会加入编译内容,使内容变多。(再提一嘴esbuild和vite加速打包,?没用过)

模板的存在,仅仅是为了让开发人员更加方便的书写界面代码
vue最终运行的时候,最终需要的是render函数,而不是模板,因此,模板中的各种语法,在虚拟dom中都是不存在的,它们都会变成虚拟dom的配置

等同于

案例:自动生成目录

现在需要制作一个组件,该组件可以根据其插槽中的内容,自动生成一个目录。


到此这篇关于关于Vue虚拟dom问题的文章就介绍到这了,更多相关Vue虚拟dom内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们

(0)

相关推荐

  • 深入理解Vue2.x的虚拟DOM diff原理

    前言 经常看到讲解Vue2的虚拟Dom diff原理的,但很多都是在原代码的基础上添加些注释等等,这里从0行代码开始实现一个Vue2的虚拟DOM 实现VNode src/core/vdom/Vnode.js export class VNode{ constructor ( tag, //标签名 children,//孩子[VNode,VNode], text, //文本节点 elm //对应的真实dom对象 ){ this.tag = tag; this.children = children

  • 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

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

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

  • 解决vue中虚拟dom,无法实时更新的问题

    碰到的问题:使用jq获取元素节点的个数时一直为0 解决方法:使用vue的nextTick()函数即可解决 原理:nextTick可以在下一次更新dom之后进行回调,我的问题在于,在页面加载完成时无法获取虚拟dom,而使用回调函数后就可以获取到正确的dom数量,所以只需要在nextTick函数中执行jq函数就可以正确获取了. self.$nextTick(function () { // DOM 更新了 $("#myCarousel").carousel(0); }) 以上这篇解决vue

  • Vue使用虚拟dom进行渲染view的方法

    前提 vue版本:v2.5.17-beta.0 触发render vue在数据更新后会自动触发view的render工作,其依赖于数据驱动:在数据驱动的工作下,每一个vue的data属性都被监听,并且在set触发时,派发事件,通知收集到的依赖,从而触发对应的操作,render工作就是其中的一个依赖,并且被每一个data属性所收集,因此每一个data属性改变后,都会触发render. vue更新监听 看一段代码 // 来自mountComponent函数 updateComponent = fun

  • vue 虚拟DOM的原理

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

  • vue 虚拟dom的patch源码分析

    本文介绍了vue 虚拟dom的patch源码分析,分享给大家,具体如下: 源码目录:src/core/vdom/patch.js function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) { let oldStartIdx = 0 let newStartIdx = 0 let oldEndIdx = oldCh.length - 1 let oldStartVnode = oldCh[0]

  • vue 源码解析之虚拟Dom-render

    vue 源码解析 --虚拟Dom-render instance/index.js function Vue (options) { if (process.env.NODE_ENV !== 'production' && !(this instanceof Vue) ) { warn('Vue is a constructor and should be called with the `new` keyword') } this._init(options) } renderMixin

  • 探究Vue.js 2.0新增的虚拟DOM

    你可能早就已经听说了 Vue.js 2.0.一个主要的令人兴奋的新特性就是更新页面的"虚拟DOM"的加入. 虚拟 DOM 可以做什么? React 和 Ember 都使用了虚拟DOM来提升页面的刷新速度.为了理解其如何工作,让我们先讨论一下几个概念: 更新DOM的花费时间非常长 当我们使用 JavaScript 来改变页面的时候,浏览器不得不做一些工作来找到需要的DOM节点,并且做出类似这样的改变: document.getElementById('myId').appendChild

随机推荐