vue的虚拟dom(Virtual DOM )

模板转换成视图的过程

在底层实现中Vue会将模板编译成渲染函数,当然我们也可以不写模板,直接写渲染函数,以获得更好的控制。

渲染函数:渲染函数是用来生成Virtual DOM的;
VNode虚拟节点:vnode可以理解成dom节点的描述对象,它描述了应该怎样去创建真实的DOM节点;
patch(patching算法):虚拟DOM最核心的部分,它可以将vnode渲染成真实的DOM。这个过程是对比新旧虚拟节点之间有哪些不同,然后根据对比结果找出需要更新的的节点进行更新。其实际作用是在现有DOM上进行修改来实现更新视图的目的;

Virtual DOM

Virtual DOM用JS对象来描述dom的节点(VNode),这个对象至少包含标签名( tag)、属性(attrs)和子元素对象( children)这三个属性。它是对真实 DOM 的抽象,最终可以通过一系列操作把这个对象转化为真实的dom。

具体步骤为

Virtual DOM 本质上就是在 JS 和 DOM 之间做了一个缓存

Virtual DOM的作用

虚拟DOM的最终目标是将虚拟节点渲染到视图上,但是如果直接使用虚拟节点覆盖旧节点的话,会有很多不必要的DOM操作。例如,一个ul标签下很多个li标签,其中只有一个li有变化,这种情况下如果使用新的ul去替代旧的ul,因为这些不必要的DOM操作而造成了性能上的浪费。
为了避免不必要的DOM操作,虚拟DOM在虚拟节点映射到视图的过程中,将虚拟节点与上一次渲染视图所使用的旧虚拟节点(oldVnode)做对比,找出真正需要更新的节点来进行DOM操作,从而避免操作其他无需改动的DOM。
其实虚拟DOM在Vue.js主要做了两件事:
提供与真实DOM节点所对应的虚拟节点vnode;
将虚拟节点vnode和旧虚拟节点oldVnode进行对比,然后更新视图;

Virtual DOM的diff算法

递归地进行同级vnode的diff,最终实现整个DOM树的更新

步骤:

用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中;
当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异;
把所记录的差异应用到所构建的真正的DOM树上,视图就更新了;

Virtual DOM的优点

跨平台的优势:由于 Virtual DOM 是以 JavaScript 对象为基础而不依赖真实平台环境,所以使它具有了跨平台的能力,比如说浏览器平台、Weex、Node 等;

提高效率:操作 DOM 慢,js运行效率高,所以将DOM对比操作放在JS层可以提高效率;

提高渲染性能:通过patch 的核心----diff 算法,找出本次DOM需要更新的节点来更新,其他的不更新。比如修改某个model 100次,从1加到100,那么有了Virtual DOM的缓存之后,只会把最后一次修改patch到view上。

nextTick

this.$nextTick(()=> {
  // 操作。。。
})

1 Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中;

2 当项目中你想在改变DOM元素的数据后基于新的dom做点什么,对新DOM一系列的js操作都需要放进Vue.nextTick()的回调函数中;

3 在使用某个第三方插件时 ,希望在vue生成的某些dom动态发生变化时重新应用该插件,也会用到该方法;

改变数据有时不更新

1 vue实现数据双向绑定有这么一个过程:当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用Object.defineProperty() 把这些属性全部转为getter/setter。每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。实现数据data变化更新视图view。

var vm = new Vue({
    data:{
        a:1;   // vm.a 是响应的
    }
})
vm.b = 2;   // vm.b 是非响应的

2 没有更新dom是因为改变数据之后Object.defineproperty()的set方法没有被触发,即没有监测到数据更新。以下几种情况会出现这个问题:

  当你利用索引直接设置数组的一项时,例如:this.items[indexOfItem] = newValue;

  当你修改数组的长度时,例如:this.items.length = newLength;

数组的push,splice等方法也不会更新dom;

  对象里边的修改:

data () {
    return {
        student: {
            name: ‘‘
        },
        teach:["李磊"]
     }
}

// 以下操作不会触发视图更新
this.student.name="XXX";

解决办法:

1 使用set:

this.$set(‘对象名‘, key, value);   // 对象写法
this.$set(this.teach,0, “韩梅梅”);   // 数组写法

2 使用deep

watch:{
    student:{
       handler:(n,o)=>{
           //逻辑处理
       },
       deep:true
    }
}

3  改变原对象或数组的地址

this.obj = Object.assign({},this.obj,{"sex","man"});

Virtual DOM更新dom的机制

原文:https://www.cnblogs.com/fundebug/p/vue-virtual-dom.html

原文地址:https://www.cnblogs.com/xjy20170907/p/12684706.html

时间: 2024-08-24 22:01:45

vue的虚拟dom(Virtual DOM )的相关文章

虚拟DOM (virtual DOM)

1.定义 虚拟dom就是一个简单的对象,包含标签名(tag).属性(attr).子元素(children),通过js操作virtual DOM,最终映射到真实的dom上. 2.为什么要用虚拟dom: 频繁地操作dom,会造成页面的回流和重绘,增加性能开销,降低页面的渲染速度. 把dom的操作放到js中,js运算速度快,提高效率: 跨平台优势,不依赖真实的环境,浏览器.node都可以实现. 3.虚拟dom在Vue中的应用: vue.js通过编译将模板转换成渲染函数render,执行渲染函数就得到一

15-什么是Virtual Dom

Virtual Dom并不是真正意义上的Dom,而是一个轻量级的JavaScript对象,在状态发生变化的时候,Virtual Dom会进行Diff运算,来更新只需要被替换的DOM,而不是全部重绘. 与DOM操作相比,Virtual Dom是基于JavaScript计算的,所以开销会小很多. 用Virtual Dom创建的JavaScript对象一般会是这样: var vNode= { tag:"div", attributes:{ id:"main" }, chi

理解 Virtual DOM(摘)及评价

框架并没有提高web的性能,只是让开发者更加专注的完成业务逻辑,而不用过渡的考虑性能上的优化.如果以性能来比的话,框架是绝对比不过优化后的原生代码的. 二.什么是Virtual DOM Virtual DOM的概念有很多解释,从我的理解来看,主要是三个方面,分别是:一个对象,两个前提,三个步骤. 一个对象指的是Virtual DOM是一个基本的JavaScript对象,也是整个Virtual DOM树的基本. 两个前提分别是JavaScript很快和直接操作DOM很慢,这是Virtual DOM

Virtual DOM的简单实现

了解React的同学都知道,React提供了一个高效的视图更新机制:Virtual DOM,因为DOM天生就慢,所以操作DOM的时候要小心翼翼,稍微改动就会触发重绘重排,大量消耗性能. 1.Virtual DOM Virtual DOM是利用JS的原生对象来模拟DOM,既然DOM是对象,我们也可以用原生的对象来表示DOM. var element = { tagName: 'ul', // 节点标签名 props: { class: 'list' // 节点的属性,ID,class... },

如何理解vue,virtual DOM

Vue.js 2.0窥探之Virtual DOM到底是什么? Vue.js 2.0已经发布,并且在其中新添加如了一些新功能.其中一个功能就是"Virtual DOM". Virtual DOM是什么? 在之前,React和Ember早就开始用虚拟DOM技术来提高页面更新的速度了. 若想了解它是如何工作的,就要先认清这几个概念: 1.更新DOM是非常昂贵的操作 当我们使用Javascript来修改我们的页面,浏览器已经做了一些工作,以找到DOM节点进行更改,例如:document.get

Vue Virtual Dom 和 Diff原理(面试必备) 极简版

我又来了,这是Vue面试三板斧的最后一招,当然也是极其简单了,先说Virtual Dom,来一句概念: 用js来模拟DOM中的节点.传说中的虚拟DOM. 再来一张图: 是不是一下子秒懂  没懂再来一张 Virtual Dom就先这样,理解了就OK,下面我们了解一下Diff,老规矩先来一句概念: diff算法就是进行虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方,最后用patch记录的消息去局部更新Dom. 换句人话 diff的过程就是调用名为patch的函数,比较新旧节点,一

Virtual DOM 虚拟DOM的理解(转)

作者:戴嘉华 转载请注明出处并保留原文链接( #13 )和作者信息. 目录: 1 前言 2 对前端应用状态管理思考 3 Virtual DOM 算法 4 算法实现 4.1 步骤一:用JS对象模拟DOM树 4.2 步骤二:比较两棵虚拟DOM树的差异 4.3 步骤三:把差异应用到真正的DOM树上 5 结语 6 References 1 前言 本文会在教你怎么用 300~400 行代码实现一个基本的 Virtual DOM 算法,并且尝试尽量把 Virtual DOM 的算法思路阐述清楚.希望在阅读本

Vue.js 2.0更新之增加Virtual DOM讲解

Virtual DOM是什么?在之前,React和Ember早就开始用虚拟DOM技术来提高页面更新的速度了. 若想了解它是如何工作的,就要先认清这几个概念:1.更新DOM是非常昂贵的操作当我们使用Javascript来修改我们的页面,浏览器已经做了一些工作,以找到DOM节点进行更改,例如: document.getElementById('myId').appendChild(myNewNode); 在现代的应用中,会有成千上万数量个DOM节点.所以因更新的时候产生的计算非常昂贵.琐碎且频繁的更

vue 之 Virtual Dom

什么是Virtual Dom Virtual Dom可以看做一棵模拟了DOM树的JavaScript树,其主要是通过vnode,实现一个无状态的组件,当组件状态发生更新时,然后触发Virtual Dom数据的变化,然后通过Virtual Dom和真实DOM的比对,再对真实DOM更新.可以简单认为Virtual Dom是真实DOM的缓存. 为什么用Virtual Dom 我们知道,当我们希望实现一个具有复杂状态的界面时,如果我们在每个可能发生变化的组件上都绑定事件,绑定字段数据,那么很快由于状态太