美文网首页
Vue原理学习(四)

Vue原理学习(四)

作者: IsaacHHH | 来源:发表于2018-05-29 10:31 被阅读74次

实现Virtual DOM 的VNode节点

在这里,我们首先要区分Virtual DOM 和VNode的意思,Virtual DOM我之前也介绍过,是虚拟DOM,相信大家也不陌生,而VNode是虚拟节点的意思。好比说JavaScript是由一堆Node节点组成的DOM树。

另外,由于Virtual DOM是抽象的JavaScript对象,所以具备了跨平台能力,因为我们完全可以根据特定规则,去渲染出对应的任意的所需要的对象。

实现一个VNode

在着手编写代码前,我们先看下的JavaScript 节点都包含哪些信息。
<a href="https://baidu.com">hi</a>
这里我写了一个a标签,可以看到,它包含了标签名href属性文本。当然,如果更复杂的一些,还会包含嵌套关系。

所以,我们可以想想,因为VNode是一个真实的DOM 节点的抽象,我们也需要这些参数:标签名、属性、文本、子标签等。

该方法VNode大概在Vue源码中736行,除了我们这里传递的参数外,其还包含了contextcomponentOptionsasyncFactory

class VNode{
  constructor(tag, data, children, text, elm) {
    // tag 标签名
    this.tag = tag
    // data 标签包含的数据信息,如前面的href属性,还有其他的如props等
    this.data = data
    // children 子节点, type:Array
    this.children = children
    // elm 当前虚拟节点对应的真实节点
    this.elm = elm
  }
}

然后我们在看来一个Vue组件。

<template>
  <span class='text' v-show='isShow'>
    I am span.
  </span>
</template>

用刚才的VNode类表示就是如下样子:

new VNode('span', {
  // 指令集合数据
  directives: [
    {
      // v-show 指令
      rawName: 'v-show',
      expression: 'isShow',
      name: 'show',
      value: true
    }
  ],
  // 静态class
  staticClass: 'text'
  // 因为文本节点也是节点,所以我们需要再次new一个VNode
  [ new VNode(undefined, undefined, undefined, 'I am span.')]
})

转换成VNode以后的代码:

{
  tag: 'span',
  data: {
    directives: [
      {
        rawName: 'v-show',
        expression: 'isShow',
        name: 'show',
        value: 'true'
      }
    ],
    staticClass: 'text',
    text: undefined,
    children: [
      {
        tag: undefined,
        data: undefined,
        text: 'I am span.',
        children: undefined
      }
    ]
  }
}

所以我们会发现,如果你的节点嵌套关系足够复杂,这里的VNode也会显得特别庞大。

另外,AST(抽象语法树,Abstract Syntax Tree),也和这个差不多。

进一步封装

通过观察上面的代码,我们可以发现,在创建VNode的过程中,会存在空节点和文本节点,这些节点都是很简单的,不需要一些属性,所以我们可以考虑将创建这两种节点的方法提取出来。

在Vue源码中,也有这两个方法, 分别是createEmptyVNodecreateTextVNode,大概在784-794行左右。

创建空节点

function createEmptyVNode() {
  const node = new VNode();
  node.text = ''
  return node;
}

创建文本节点

function createTextVNode(val) {
  return new VNode(undefined, undefined, undefined, String(val))
}

克隆一个VNode节点

有时候,我们需要一个一摸一样的VNode节点,此时,我们只需要提取出来一个克隆方法即可。

该方法cloneVNode在Vue源码中也存在,大概在802行左右。

function cloneVNode(node) {
  const cloneVNode = new VNode(
    node.tag,
    node.data,
    node.children,
    node.text,
    node.elm
  );
  return cloneVNode;
}

这里克隆节点,除了包含以上属性外,还应该包含如:节点注释、节点key等等。

总结

VNode就是一些虚拟的节点,从而构成了Virtual DOM。并且嵌套关系越深,构建出来的VNode对象也越复杂,这个过程中,由于存在空的节点和文本节点,这两个节点不需要额外的属性,所以我们将创建方法抽取了出来。

相关文章

  • 前端TODO

    Vue.js 等框架原理了解 webpack 原理了解 browserify 插件开发 Vue.js 等框架原理学习

  • Vue原理学习(四)

    实现Virtual DOM 的VNode节点 在这里,我们首先要区分Virtual DOM 和VNode的意思,V...

  • 最近的学习方向

    vue问题 vuex学习、vue-router路由管理、vue3学习 js学习 js原理机制、es6规范、一些常用...

  • Vue学习笔记---暂保存

    Vue的学习笔记 一 Vue基本 1. Vue的设计理念 Vue响应式原理[https://www.process...

  • vue工作学习索引

    vue原理与认知 相关的整理 vue原理学习1 简书地址[https://www.jianshu.com/p/ff...

  • vue总结

    vue路由守卫 vue实现双向绑定原理 Vue生命周期: vue跨域方式 vue-router实现原理 vue-r...

  • Vue原理学习(三)

    响应式依赖收集原理 在Vue原理学习 (二)中,介绍Object.defineProperty中的[[Getter...

  • 面试总结之基础(2)

    Vue2响应式原理 Vue3响应式原理

  • vue原理面试题资源整理

    vuex面试题 Vue生命周期 周期2 Vue通信 父子 兄弟 Vue响应式原理 MVVM Vue axios原理...

  • 前端面试资料收集

    vue相关知识 前端面试题+前端学习+面试指南 剖析Vue原理&实现双向绑定MVVM 详解 JavaScript的...

网友评论

      本文标题:Vue原理学习(四)

      本文链接:https://www.haomeiwen.com/subject/vcjojftx.html