Vue虚拟DOM是这样实现的

news/2024/7/10 1:43:54 标签: vue, vue.js

Vue虚拟DOM

    • 1.什么是虚拟DOM?
    • 2.为什么使用虚拟DOM
    • 3.Vue中的虚拟DOM
    • 4.VNode类的作用

1.什么是虚拟DOM?

虚拟DOM就是通过一个JS对象来描述一个DOM节点,比如

<div class="a" id="b">我是内容</div>
{
tag:'div', // 元素标签
attrs:{ // 属性
class:'a',
id:'b'
},
text:'我是内容', // 文本内容
children:[] // 子元素}

通过下面对象描述的方式,将上面的div标签描述出来

2.为什么使用虚拟DOM

我们都知道Vue采用的是MVVM的框,核心思想就是通过数据控制视图,当时数据发生后变化的时候视图也要发生对应的变化,如果不采用虚拟DOM技术,每一次都去操作真实的DOM树那么在性能方面的消耗将会是非常大的。采用虚拟DOM的方式通过JS模拟出的DOM节点,在每次数据法还是能变化的时候我们只需要通过Diff算法来对比计算出需要更新的节点,这样会大大提升视图层渲染性能。

3.Vue中的虚拟DOM

Vue中的虚拟DOM主要通过VNode类实现,以下是VNode类的源码

export default class VNode {
constructor (
tag?: string,
data?: VNodeData,
children?: ?Array<VNode>,
text?: string,
elm?: Node,
context?: Component,
componentOptions?: VNodeComponentOptions,
asyncFactory?: Function
) {
this.tag = tag /*当前节点的标签名*/
this.data = data /*当前节点对应的对象,包含了具体的一些数据信息,是一个VNodeData类型,可以参考VNodeData类型中的数据信息*/
this.children = children /*当前节点的子节点,是一个数组*/
this.text = text /*当前节点的文本*/
this.elm = elm /*当前虚拟节点对应的真实dom节点*/
this.ns = undefined /*当前节点的名字空间*/
this.context = context /*当前组件节点对应的Vue实例*/
this.fnContext = undefined /*函数式组件对应的Vue实例*/
this.fnOptions = undefined
this.fnScopeId = undefined
this.key = data && data.key /*节点的key属性,被当作节点的标志,用以优化*/
this.componentOptions = componentOptions /*组件的option选项*/
this.componentInstance = undefined /*当前节点对应的组件的实例*/
this.parent = undefined /*当前节点的父节点*/
this.raw = false /*简而言之就是是否为原生HTML或只是普通文本,innerHTML的时候为true,textContent的时候为false*/
this.isStatic = false /*静态节点标志*/
this.isRootInsert = true /*是否作为跟节点插入*/
this.isComment = false /*是否为注释节点*/
this.isCloned = false /*是否为克隆节点*/
this.isOnce = false /*是否有v-once指令*/
this.asyncFactory = asyncFactory
this.asyncMeta = undefined
this.isAsyncPlaceholder = false
}
get child (): Component | void {
return this.componentInstance
}}

VNode的类型
VNode类中只有三种类型的节点可以被创建和插入到DOM中分别是元素节点,文本节点,注释节点。

  • 注释节点

描述一个注释节点,只需要传入两个属性,即:text和isComment,text代表的是传入的具体注释信息,isComment代表的则是该节点是不是注释节点,返回一个布尔值

// 创建注释节点
export const createEmptyVNode = (text: string = '') => {
const node = new VNode()
node.text = text
node.isComment = true
return node
}
  • 文本节点

只需要一个属性,那就是text属性,用来表示具体的文本信息。

// 创建文本节点
export function createTextVNode (val: string | number) {
return new VNode(undefined, undefined, undefined, String(val))}

  • 元素节点

元素节点是比较接近我们日常所接触的DOM树,元素节点的作用就是要将这样的html5标签拆分成为包含tag,data,attribute,children等属性的一个Js对象,方便进行DOM更新。

// 真实DOM节点
<div id='a'><span>元素节点</span></div>
// VNode节点
{
tag:'div',
data:{},
children:[
{
tag:'span',
text:'元素节点'
}
]}
  • 组件节点

组件其实就是一个可以服用的UI代码片段,那么本质上就是有多个html标签组成的,这样组件本质上和元素节点是相同的,但是组件和元素节点还是有区别的,组件会有自身的一些属性,比如props,以及该组件对应的Vue实例。

componentOptions :组件的option选项,如组件的props等
componentInstance :当前组件节点对应的Vue实例

  • 函数式组件节点
fnContext:函数式组件对应的Vue实例
fnOptions: 组件的option选项

4.VNode类的作用

其实VNode的作用是相当大的。我们在视图渲染之前,把写好的template模板先编译成VNode并缓存下来,等到数据发生变化页面需要重新渲染的时候,我们把数据发生变化后生成的VNode与前一次缓存下来的VNode进行对比,找出差异,然后有差异的VNode对应的真实DOM节点就是需要重新渲染的节点,最后根据有差异的VNode创建出真实的DOM节点再插入到视图中,最终完成一次视图更新。


http://www.niftyadmin.cn/n/1319085.html

相关文章

JDK1.5 Queue

JDK1.5 Queue LinkedList&#xff1a; LinkedList不是同步的。如果多个线程同时访问列表&#xff0c;而其中至少一个线程从结构上修改了该列表&#xff0c;则它必须 保持外部同步。&#xff08;结构修改指添加或删除一个或多个元素的任何操作&#xff1b;仅设置元素的值不是结构…

Vue中的Diff算法实现过程

目录1.Diff的由来&#xff1f;2.如何实现&#xff1f;1.Diff的由来&#xff1f; Vue利用双向绑定原理&#xff0c;实现了视图层和数据层的同时更新&#xff0c;在数据层发生变化的时候利用虚拟DOM去更新对应的DOM树&#xff0c;那么新DOM树和旧DOM树如何去比对&#xff0c;DOM…

ASP.NET MVC 如何实现头压缩

网页的头部压缩在页面体积大的情况下非常有必要做&#xff0c;它会使页面体积有一个明显的减小&#xff0c;同时加到网页从服务端下载到客户端的速度&#xff0c;以下是我做的一个测试&#xff1a; 没有使用头压缩时&#xff1a; 使用了头压缩后&#xff1a; 我们可以看到&…

JDK1.5 生产消费者

ArrayBlockingQueue&#xff1a; 一个由数组支持的有界阻塞队列。此队列按 FIFO&#xff08;先进先出&#xff09;原则对元素进行排序。队列的头部 是在队列中存在时间最长的元素。队列的尾部 是在队列中存在时间最短的元素。新元素插入到队列的尾部&#xff0c;队列检索操作则…

什么是vue?如何理解双向数据绑定?Vue2.0和Vue3.0实现双向绑定的区别

1.何为Vue&#xff1f; Vue是一套用于构建单页面应用的JavaScript框架&#xff0c;它的核心采用MVVM框架进行搭建&#xff0c;自底向下增量开发&#xff0c;主要的特点就是实现了数据的双向绑定&#xff0c;通过渐进式的开发模式减小项目包体积&#xff0c;采用模块化开发的思…

WPF附加属性

1、定义&#xff1a;一个属性原来不属于某个对象&#xff0c;但由于某种需求而被后来附加上去。附加属性的本质是依赖属性。 2、作用&#xff1a;将属性与数据类型解耦&#xff0c;让数据类型的设计的更加灵活。 3、举例&#xff1a;Human&#xff0c;School。Human中的一个人&…

JDK1.5 Condition接口

Condition 将 Object 监视器方法&#xff08;wait、notify和 notifyAll&#xff09;分解成截然不同的对象&#xff0c;以便通过将这些对象与任意 Lock 实现组合使用&#xff0c;为每个对象提供多个等待 set &#xff08;wait-set&#xff09;。其中&#xff0c;Lock 替代了 syn…

Vue中常见的指令介绍以及那些我踩过的坑

这篇文章继续给各位前端程序员们介绍Vue相关的技术点。这篇文章主要分为以下几个部分&#xff1a; 何为指令&#xff1f; 指令的定义 常见的指令有哪些 指令的定义&#xff1f; 指令&#xff0c;说到指令其实就是操作DOM树的一些内置指令&#xff0c;大家都知道Vue采用虚拟…