虾米带你轻松搞定Vuejs 系列

版权声明:博主文章皆为原创,转载请注明,谢谢 https://blog.csdn.net/bensen1989/article/details/89883951

(十六)Virtual DOM(如何实现Virtual DOM的VNode节点)

哈喽~,将近有4个月没有写点东西了,今天终于挤出来一点时间,继续整体之前预计完成的vue进阶的笔记。今天主要探索虚拟DOM;
首先我们需要知道什么是VNode。

什么是VNode

我们知道,render function 会被转化成VNode节点。Virtual DOM其实就是一颗以javascript对象(VNode节点)作为基础的树,
用对象属性来描述节点,实际上他只是一层对真实DOM的抽象。最中可以通过一系列的操作使这棵树映射到真实环境中。由于Virtual DOM是以javascript对象为基础而不依赖于真实平台环境,所以使它具备了扩平台的能力,这里的跨平台是指浏览器平台、weex、Node等等。

实现一个VNode

Vnode说白了就是一个javascript对象,只要这个类的属性可以正确直观的描述清楚当前节点的信息即可。好像这么说还是不清楚,下边我们实现一个简单的Vnode类‘加入一些基本属性,我们有简单到复杂的讲解。首先我们不考虑复杂情况。

class VNode {
  constructor(tag, data, children, text, elm) {
    /*当前节点的标签名*/
    this.tag = tag
    /*当前节点的一些数据信息,比如props、attrs等数据*/
    this.data = data
    /*当前节点的子节点,是一个数组*/
    this.children = children
    /*当前节点的文本*/
    this.text = text
    /* 当前虚拟节点对应的真实dom节点 */
    this.elm = elm
  };
};

上述代码中可能看的不够透彻,我们再举个例子,根据实际场景来看一看。

<template>
  <span class="demo" v-show="isShow">这是一个简单的元素.</span>
</template>

那我们用javascript的方式怎么写?接下里我们探讨一下

function render () {
  return new VNode(
      'span',
      {
          /* 指令集合数组 */
          directives: [
              {
                  /* v-show指令 */
                  rawName: 'v-show',
                  expression: 'isShow',
                  name: 'show',
                  value: true
              }
          ],
          /* 静态class */
          staticClass: 'demo'
      },
      [ new VNode(undefined, undefined, undefined, '这是一个简单的元素.') ]
  );
}

我们这里想一下转化成VNode以后的情况。

{
    tag: 'span',
    data: {
        /* 指令集合数组 */
        directives: [
            {
                /* v-show指令 */
                rawName: 'v-show',
                expression: 'isShow',
                name: 'show',
                value: true
            }
        ],
        /* 静态class */
        staticClass: 'demo'
    },
    text: undefined,
    children: [
        /* 子节点是一个文本VNode节点 */
        {
            tag: undefined,
            data: undefined,
            text: '这是一个简单的元素.',
            children: undefined
        }
    ]
}

上边讲述了转化VNode的情况的一个简单场景,了解了这些我们做一些常用VNode的功能,然后我们可以将 VNode 进一步封装一下,可以实现一些产生常用 VNode 的方法。

  • 创建一个空节点
function createEmptyVNode () {
    const node = new VNode();
    node.text = '';
    return node;
}
  • 创建一个纯文本节点
function createTextVNode (val) {
 return new VNode(undefined, undefined, undefined, String(val));
}
  • 克隆一个节点
function cloneVNode (node) {
    const cloneVnode = new VNode(
        node.tag,
        node.data,
        node.children,
        node.text,
        node.elm
    );
    return cloneVnode;
}

总结

我们总结一下,其实VNode 就是一个 JavaScript 对象,用 JavaScript 对象的属性来描述当前节点的一些状态,用 VNode 节点的形式来模拟一棵 Virtual DOM 树

猜你喜欢

转载自blog.csdn.net/bensen1989/article/details/89883951