暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Vue中 Vnode的创建与处理(1)

小王学前端 2021-04-05
2394

什么是虚拟DOM

为什么要使用虚拟DOM:

h函数

Vnode的创建过程

VNode 的处理过程

文章比较长,首先先看一下vnode的创建和处理过程的简要(源码下面都有注释,需要可以细看):

什么是虚拟DOM

虚拟DOM(Virtual DOM)是使用JavaScript对象描述真实DOM

Vue.js中的虚拟DOM借鉴Snabbdom,并添加了Vue.js的特征,例如:指令和组件机制

为什么要使用虚拟DOM:

避免直接操作真实DOM,提高开发效率

作为一个中间层可以跨平台,支持web端渲染,还可以支持服务端渲染

虚拟DOM不一定可以提高性能:

首次渲染的时候会增加开销

复杂视图情况下提升渲染性能

h函数

vm.$createElement(tag, data, children, normalizeChildren)

tag:标签名或者组件对象

data:描述tag,可以设置DOM的属性或者标签的属性

children:tag中的文本内容或者子节点

render(h){

  // h(tag, data, children)

  // return h('h1', this.msg)

  // return h('h1', {domProps: {innerHTML: this.msg}})

  // return h('h1', {attrs: {id: 'title'}}, this.msg)

  

  // children 当前h1对应的子节点

  // data 创建函数时传递的data选项

  // elm 真实dom

  // tag 调用h函数时传递的第一个属性

  const vnode = h(

    'h1',

    {

      attrs: {

        id:'title'   //设置属性id   可以在css 里面设置样式

      }

    },

    this.msg

  )

  console.log(vnode);

  return vnode;

}

vNode核心属性:tag, data,children,text,elm,key

VNode就是用JS对象描述一个真实的DOM

为什么使用VNode:真实DOM有很多无用的属性,且操作DOM对性能消耗比较大;

VNode的作用:渲染前将templatem模版编译成VNode缓存,然后数据更新后对比新旧vnode,根据有变化的vnode创建出真实的节点插入到视图中完成一次视图更新。

源码中通过VNode类实例化不同的虚拟节点;

VNode节点类型分为注释节点,文本节点,元素节点,组件节点,函数式节点,克隆节点;

创建不同类型的节点调用不同的方法如createEmptyVNode,createTetVNode等,不同节点生成的属性不同。


DOM-Diff

对比vnode的算法叫做DOM-Diff算法,这个过程叫做patch过程,其中对比新旧vnode以新的为基准,操作旧的vnode;

对比新旧节点后的操作分为创建、删除、更新。

创建

删除

获取父节点,parent.removeChildren();

更新

更新需要判断新旧节点的类型,看图。难点是新旧节点都有子节点的情况,需要循环对比。

更新子节点

比较复杂的情况便是新旧vnode都是有子节点的节点,那么对比后的执行创建子节点、删除~、移动~、更新~的操作。外层循环newVnode内层循环oldVnode,对比新的操作旧的。

注意的是新增和移动为了避免在与其它操作的节点冲突,目标位置应该选择未处理的节点之前而不是已处理之后。

优化策略

进行四步对比,详见链接,思路是四个游标,从两边向中间循环,如果新前和新后相遇了 那么旧前和旧后之间的节点旧删掉,如果旧前旧后相遇了,那么新前新后中间的便是新节点,截取后插入。四步对比没有相同的便双重循环新旧vnode;



文章转载自小王学前端,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论